You can subscribe to this list here.
| 2002 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(22) |
Nov
(308) |
Dec
(131) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2003 |
Jan
(369) |
Feb
(171) |
Mar
(236) |
Apr
(187) |
May
(218) |
Jun
(217) |
Jul
(127) |
Aug
(448) |
Sep
(270) |
Oct
(231) |
Nov
(422) |
Dec
(255) |
| 2004 |
Jan
(111) |
Feb
(73) |
Mar
(338) |
Apr
(351) |
May
(349) |
Jun
(495) |
Jul
(394) |
Aug
(1048) |
Sep
(499) |
Oct
(142) |
Nov
(269) |
Dec
(638) |
| 2005 |
Jan
(825) |
Feb
(1272) |
Mar
(593) |
Apr
(690) |
May
(950) |
Jun
(958) |
Jul
(767) |
Aug
(839) |
Sep
(525) |
Oct
(449) |
Nov
(585) |
Dec
(455) |
| 2006 |
Jan
(603) |
Feb
(656) |
Mar
(195) |
Apr
(114) |
May
(136) |
Jun
(100) |
Jul
(128) |
Aug
(68) |
Sep
(7) |
Oct
(1) |
Nov
(1) |
Dec
(8) |
| 2007 |
Jan
(4) |
Feb
(3) |
Mar
(8) |
Apr
(16) |
May
(5) |
Jun
(4) |
Jul
(6) |
Aug
(23) |
Sep
(15) |
Oct
(5) |
Nov
(7) |
Dec
(5) |
| 2008 |
Jan
(5) |
Feb
(1) |
Mar
(1) |
Apr
(5) |
May
(1) |
Jun
(1) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(1) |
Dec
|
| 2009 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(1) |
Aug
|
Sep
|
Oct
|
Nov
(1) |
Dec
|
| 2011 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(1) |
| 2012 |
Jan
|
Feb
|
Mar
|
Apr
(1) |
May
|
Jun
(1) |
Jul
(1) |
Aug
(1) |
Sep
|
Oct
(2) |
Nov
(3) |
Dec
(2) |
| 2013 |
Jan
(1) |
Feb
|
Mar
(2) |
Apr
(1) |
May
|
Jun
|
Jul
(1) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
| 2014 |
Jan
|
Feb
|
Mar
(1) |
Apr
|
May
(2) |
Jun
(1) |
Jul
|
Aug
(1) |
Sep
(1) |
Oct
|
Nov
(1) |
Dec
|
| 2015 |
Jan
|
Feb
|
Mar
|
Apr
(1) |
May
|
Jun
|
Jul
|
Aug
|
Sep
(1) |
Oct
|
Nov
|
Dec
|
| 2016 |
Jan
|
Feb
|
Mar
(1) |
Apr
|
May
(1) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
| 2017 |
Jan
(1) |
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(1) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
|
From: <hib...@li...> - 2006-03-27 15:49:19
|
Author: epbernard
Date: 2006-03-27 10:48:23 -0500 (Mon, 27 Mar 2006)
New Revision: 9685
Modified:
trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/AbstractEntityManagerImpl.java
trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/transaction/JoinableCMTTransaction.java
Log:
Fix some nasty bugs regarding transaction joining and postponned closing
Modified: trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/AbstractEntityManagerImpl.java
===================================================================
--- trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/AbstractEntityManagerImpl.java 2006-03-27 08:51:36 UTC (rev 9684)
+++ trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/AbstractEntityManagerImpl.java 2006-03-27 15:48:23 UTC (rev 9685)
@@ -446,7 +446,7 @@
boolean flush = false;
TransactionFactory.Context ctx = null;
try {
- ctx = (TransactionFactory.Context) getSession();
+ ctx = (TransactionFactory.Context) session;
JoinableCMTTransaction joinable = (JoinableCMTTransaction) session.getTransaction();
flush = !ctx.isFlushModeNever() &&
//ctx.isFlushBeforeCompletionEnabled() &&
Modified: trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/transaction/JoinableCMTTransaction.java
===================================================================
--- trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/transaction/JoinableCMTTransaction.java 2006-03-27 08:51:36 UTC (rev 9684)
+++ trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/transaction/JoinableCMTTransaction.java 2006-03-27 15:48:23 UTC (rev 9685)
@@ -20,14 +20,25 @@
private JoinStatus status;
public JoinableCMTTransaction( JDBCContext jdbcContext, TransactionFactory.Context transactionContext ) {
super( jdbcContext, transactionContext );
- status = JoinStatus.MARKED_FOR_JOINED;
- tryJoiningTransaction();
+ //status = JoinStatus.MARKED_FOR_JOINED;
+ //tryJoiningTransaction();
}
public boolean isTransactionInProgress(
JDBCContext jdbcContext,
TransactionFactory.Context transactionContext) {
try {
+ return status == JoinStatus.JOINED && JTAHelper.isTransactionInProgress(
+ transactionContext.getFactory().getTransactionManager().getTransaction()
+ );
+ }
+ catch( SystemException se ) {
+ throw new TransactionException( "Unable to check transaction status", se );
+ }
+ }
+
+ private boolean isTransactionInProgress() {
+ try {
return JTAHelper.isTransactionInProgress(
transactionContext.getFactory().getTransactionManager().getTransaction()
);
@@ -39,7 +50,7 @@
void tryJoiningTransaction() {
if (status == JoinStatus.MARKED_FOR_JOINED) {
- if ( isTransactionInProgress(jdbcContext, transactionContext) ) {
+ if ( isTransactionInProgress() ) {
status = JoinStatus.JOINED;
}
else {
|
|
From: <hib...@li...> - 2006-03-27 08:51:40
|
Author: epbernard
Date: 2006-03-27 03:51:36 -0500 (Mon, 27 Mar 2006)
New Revision: 9684
Modified:
trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/AbstractEntityManagerImpl.java
trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/Ejb3Configuration.java
Log:
Add register sync when EM is created inside a Tx
Modified: trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/AbstractEntityManagerImpl.java
===================================================================
--- trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/AbstractEntityManagerImpl.java 2006-03-27 08:47:11 UTC (rev 9683)
+++ trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/AbstractEntityManagerImpl.java 2006-03-27 08:51:36 UTC (rev 9684)
@@ -68,8 +68,7 @@
protected void postInit() {
//register in Sync if needed
- getSession().getTransaction(); // joinable transaction needs to initialize if possible
- getSession().isOpen(); //to register transaction
+ if ( PersistenceUnitTransactionType.JTA.equals(transactionType) ) joinTransaction( true );
}
public Query createQuery(String ejbqlString) {
@@ -404,9 +403,15 @@
}
public void joinTransaction() {
+ joinTransaction( false );
+ }
+
+ private void joinTransaction(boolean ignoreNotJoining) {
//set the joined status
+ getSession().isOpen(); //for sync
if ( transactionType == PersistenceUnitTransactionType.JTA ) {
try {
+ log.debug( "Looking for a JTA transaction to join" );
final Session session = getSession();
final Transaction transaction = session.getTransaction();
if ( transaction != null && transaction instanceof JoinableCMTTransaction ) {
@@ -414,12 +419,19 @@
final JoinableCMTTransaction joinableCMTTransaction = (JoinableCMTTransaction) session.getTransaction();
if ( joinableCMTTransaction.getStatus() == JoinableCMTTransaction.JoinStatus.JOINED ) {
+ log.debug("Transaction already joined");
return; //no-op
}
joinableCMTTransaction.markForJoined();
session.isOpen(); //register to the Tx
if ( joinableCMTTransaction.getStatus() == JoinableCMTTransaction.JoinStatus.NOT_JOINED ) {
- throw new TransactionRequiredException( "No active JTA transaction on joinTransaction call" );
+ if (ignoreNotJoining) {
+ log.debug( "No JTA transaction found" );
+ return;
+ }
+ else {
+ throw new TransactionRequiredException( "No active JTA transaction on joinTransaction call" );
+ }
}
else
if ( joinableCMTTransaction.getStatus() == JoinableCMTTransaction.JoinStatus.MARKED_FOR_JOINED ) {
@@ -427,6 +439,7 @@
}
//flush before completion and
//register clear on rollback
+ log.trace("Adding flush() and close() synchronization");
joinableCMTTransaction.registerSynchronization(
new Synchronization() {
public void beforeCompletion() {
@@ -459,6 +472,9 @@
log.trace( "automatically flushing session" );
ctx.managedFlush();
}
+ else {
+ log.trace( "skipping managed flushing" );
+ }
}
catch (RuntimeException re) {
//throwPersistenceException will mark the transaction as rollbacked
@@ -489,11 +505,17 @@
}
);
}
+ else {
+ log.warn("Cannot join transaction, not a JoinableCMTTransaction");
+ }
}
catch (HibernateException he) {
throwPersistenceException( he );
}
}
+ else {
+ if (!ignoreNotJoining) log.warn("Calling joinTransaction() on a non JTA EntityManager");
+ }
}
/**
Modified: trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/Ejb3Configuration.java
===================================================================
--- trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/Ejb3Configuration.java 2006-03-27 08:47:11 UTC (rev 9683)
+++ trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/Ejb3Configuration.java 2006-03-27 08:51:36 UTC (rev 9684)
@@ -240,74 +240,79 @@
if ( ! info.getClassLoader().equals( contextClassLoader ) ) {
thread.setContextClassLoader( info.getClassLoader() );
}
+ EntityManagerFactory entityManagerFactory;
- Map workingVars = new HashMap();
- workingVars.put( HibernatePersistence.PERSISTENCE_UNIT_NAME, info.getPersistenceUnitName() );
- List<String> entities = new ArrayList<String>( 50 );
- if ( info.getManagedClassNames() != null ) entities.addAll( info.getManagedClassNames() );
- List<InputStream> hbmFiles = new ArrayList<InputStream>();
- List<String> packages = new ArrayList<String>();
-// Object overridenTxType = integration.get( HibernatePersistence.TRANSACTION_TYPE );
-// if (overridenTxType != null) {
-// defineTransactionType( overridenTxType, info.getPersistenceUnitName() );
-// }
-// else {
- defineTransactionType( info.getTransactionType(), info.getPersistenceUnitName() );
-// }
- //workingVars.put( HibernatePersistence.TRANSACTION_TYPE, transactionType );
- boolean[] detectArtifact = getDetectedArtifacts( info.getProperties(), null );
- for ( URL jar : info.getJarFileUrls() ) {
- if ( detectArtifact[0] ) scanForClasses( jar, packages, entities );
- if ( detectArtifact[1] ) scanForHbmXmlFiles( jar, hbmFiles );
- }
- if ( ! info.excludeUnlistedClasses() ) {
- if ( detectArtifact[0] ) scanForClasses( info.getPersistenceUnitRootUrl(), packages, entities );
- if ( detectArtifact[1] ) scanForHbmXmlFiles( info.getPersistenceUnitRootUrl(), hbmFiles );
- }
+ try {
+ Map workingVars = new HashMap();
+ workingVars.put( HibernatePersistence.PERSISTENCE_UNIT_NAME, info.getPersistenceUnitName() );
+ List<String> entities = new ArrayList<String>( 50 );
+ if ( info.getManagedClassNames() != null ) entities.addAll( info.getManagedClassNames() );
+ List<InputStream> hbmFiles = new ArrayList<InputStream>();
+ List<String> packages = new ArrayList<String>();
+ // Object overridenTxType = integration.get( HibernatePersistence.TRANSACTION_TYPE );
+ // if (overridenTxType != null) {
+ // defineTransactionType( overridenTxType, info.getPersistenceUnitName() );
+ // }
+ // else {
+ defineTransactionType( info.getTransactionType(), info.getPersistenceUnitName() );
+ // }
+ //workingVars.put( HibernatePersistence.TRANSACTION_TYPE, transactionType );
+ boolean[] detectArtifact = getDetectedArtifacts( info.getProperties(), null );
+ for ( URL jar : info.getJarFileUrls() ) {
+ if ( detectArtifact[0] ) scanForClasses( jar, packages, entities );
+ if ( detectArtifact[1] ) scanForHbmXmlFiles( jar, hbmFiles );
+ }
+ if ( ! info.excludeUnlistedClasses() ) {
+ if ( detectArtifact[0] ) scanForClasses( info.getPersistenceUnitRootUrl(), packages, entities );
+ if ( detectArtifact[1] ) scanForHbmXmlFiles( info.getPersistenceUnitRootUrl(), hbmFiles );
+ }
- Properties properties = info.getProperties() != null ?
- info.getProperties() :
- new Properties();
- for ( Map.Entry entry : (Set<Map.Entry>) integration.entrySet() ) {
- if ( entry.getKey() instanceof String && entry.getValue() instanceof String ) {
- properties.setProperty( (String) entry.getKey(), (String) entry.getValue() );
+ Properties properties = info.getProperties() != null ?
+ info.getProperties() :
+ new Properties();
+ for ( Map.Entry entry : (Set<Map.Entry>) integration.entrySet() ) {
+ if ( entry.getKey() instanceof String && entry.getValue() instanceof String ) {
+ properties.setProperty( (String) entry.getKey(), (String) entry.getValue() );
+ }
}
- }
- //FIXME send the appropriate entites.
- if ( "true".equalsIgnoreCase( properties.getProperty(HibernatePersistence.USE_CLASS_ENHANCER) ) ) {
- info.addTransformer( new InterceptFieldClassFileTransformer( entities ) );
- }
+ //FIXME send the appropriate entites.
+ if ( "true".equalsIgnoreCase( properties.getProperty(HibernatePersistence.USE_CLASS_ENHANCER) ) ) {
+ info.addTransformer( new InterceptFieldClassFileTransformer( entities ) );
+ }
- workingVars.put( HibernatePersistence.CLASS_NAMES, entities );
- workingVars.put( HibernatePersistence.PACKAGE_NAMES, packages );
- if ( hbmFiles.size() > 0 ) workingVars.put( HibernatePersistence.HBXML_FILES, hbmFiles );
+ workingVars.put( HibernatePersistence.CLASS_NAMES, entities );
+ workingVars.put( HibernatePersistence.PACKAGE_NAMES, packages );
+ if ( hbmFiles.size() > 0 ) workingVars.put( HibernatePersistence.HBXML_FILES, hbmFiles );
- //datasources
- boolean overridenDatasource = false;
- String dataSource = (String) integration.get( HibernatePersistence.JTA_DATASOURCE );
- if (dataSource != null) {
- overridenDatasource = true;
- properties.setProperty( Environment.DATASOURCE, dataSource );
- }
- dataSource = (String) integration.get( HibernatePersistence.NON_JTA_DATASOURCE );
- if (dataSource != null) {
- overridenDatasource = true;
- properties.setProperty( Environment.DATASOURCE, dataSource );
- }
+ //datasources
+ boolean overridenDatasource = false;
+ String dataSource = (String) integration.get( HibernatePersistence.JTA_DATASOURCE );
+ if (dataSource != null) {
+ overridenDatasource = true;
+ properties.setProperty( Environment.DATASOURCE, dataSource );
+ }
+ dataSource = (String) integration.get( HibernatePersistence.NON_JTA_DATASOURCE );
+ if (dataSource != null) {
+ overridenDatasource = true;
+ properties.setProperty( Environment.DATASOURCE, dataSource );
+ }
- if ( ! overridenDatasource && (info.getJtaDataSource() != null || info.getNonJtaDataSource() != null ) ) {
- this.setDataSource(
- info.getJtaDataSource() != null ? info.getJtaDataSource() : info.getNonJtaDataSource()
- );
- this.setProperty( Environment.CONNECTION_PROVIDER, InjectedDataSourceConnectionProvider.class.getName() );
- }
+ if ( ! overridenDatasource && (info.getJtaDataSource() != null || info.getNonJtaDataSource() != null ) ) {
+ this.setDataSource(
+ info.getJtaDataSource() != null ? info.getJtaDataSource() : info.getNonJtaDataSource()
+ );
+ this.setProperty( Environment.CONNECTION_PROVIDER, InjectedDataSourceConnectionProvider.class.getName() );
+ }
- EntityManagerFactory entityManagerFactory = createEntityManagerFactory( properties, workingVars );
- //After EMF, set the CCL back
- if ( ! info.getClassLoader().equals( contextClassLoader ) ) {
- thread.setContextClassLoader( contextClassLoader );
+ entityManagerFactory = createEntityManagerFactory( properties, workingVars );
}
+ finally {
+ //After EMF, set the CCL back
+ if ( ! info.getClassLoader().equals( contextClassLoader ) ) {
+ thread.setContextClassLoader( contextClassLoader );
+ }
+ }
return entityManagerFactory;
}
|
|
From: <hib...@li...> - 2006-03-27 08:47:17
|
Author: epbernard
Date: 2006-03-27 03:47:11 -0500 (Mon, 27 Mar 2006)
New Revision: 9683
Modified:
trunk/HibernateExt/metadata/lib/ejb3-persistence.jar
trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/DefaultComponentSafeNamingStrategy.java
trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/PropertyInferredData.java
Log:
ANN-291
Modified: trunk/HibernateExt/metadata/lib/ejb3-persistence.jar
===================================================================
(Binary files differ)
Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/DefaultComponentSafeNamingStrategy.java
===================================================================
--- trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/DefaultComponentSafeNamingStrategy.java 2006-03-24 19:20:01 UTC (rev 9682)
+++ trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/DefaultComponentSafeNamingStrategy.java 2006-03-27 08:47:11 UTC (rev 9683)
@@ -10,7 +10,7 @@
public class DefaultComponentSafeNamingStrategy extends EJB3NamingStrategy {
public static final NamingStrategy INSTANCE = new DefaultComponentSafeNamingStrategy();
- private static String addUnderscores(String name) {
+ protected static String addUnderscores(String name) {
return name.replace('.', '_').toLowerCase();
}
Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/PropertyInferredData.java
===================================================================
--- trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/PropertyInferredData.java 2006-03-24 19:20:01 UTC (rev 9682)
+++ trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/PropertyInferredData.java 2006-03-27 08:47:11 UTC (rev 9683)
@@ -19,10 +19,6 @@
/**
* Take the annoted element for lazy process
- *
- * @param annotedElt
- * element to process
- * @param propertyAccessor
*/
public PropertyInferredData( XProperty property, String propertyAccessor ) {
this.property = property;
|
|
From: <pt...@12...> - 2006-03-27 03:26:55
|
aGliZXJuYXRlLWNvbW1pdHMtcmVxdWVzdCzE+rrDo6ENCg0KCQ0KDQo9PT09PT09IDIwMDYtMDMt MjAgMTM6MDM6MzYgxPrU2sC00MXW0NC0tcCjuj09PT09PT0NCg0KPg0KPlNlbmQgaGliZXJuYXRl LWNvbW1pdHMgbWFpbGluZyBsaXN0IHN1Ym1pc3Npb25zIHRvDQo+CWhpYmVybmF0ZS1jb21taXRz QGxpc3RzLnNvdXJjZWZvcmdlLm5ldA0KPg0KPlRvIHN1YnNjcmliZSBvciB1bnN1YnNjcmliZSB2 aWEgdGhlIFdvcmxkIFdpZGUgV2ViLCB2aXNpdA0KPglodHRwczovL2xpc3RzLnNvdXJjZWZvcmdl Lm5ldC9saXN0cy9saXN0aW5mby9oaWJlcm5hdGUtY29tbWl0cw0KPm9yLCB2aWEgZW1haWwsIHNl bmQgYSBtZXNzYWdlIHdpdGggc3ViamVjdCBvciBib2R5ICdoZWxwJyB0bw0KPgloaWJlcm5hdGUt Y29tbWl0cy1yZXF1ZXN0QGxpc3RzLnNvdXJjZWZvcmdlLm5ldA0KPg0KPllvdSBjYW4gcmVhY2gg dGhlIHBlcnNvbiBtYW5hZ2luZyB0aGUgbGlzdCBhdA0KPgloaWJlcm5hdGUtY29tbWl0cy1hZG1p bkBsaXN0cy5zb3VyY2Vmb3JnZS5uZXQNCj4NCj5XaGVuIHJlcGx5aW5nLCBwbGVhc2UgZWRpdCB5 b3VyIFN1YmplY3QgbGluZSBzbyBpdCBpcyBtb3JlIHNwZWNpZmljDQo+dGhhbiAiUmU6IENvbnRl bnRzIG9mIGhpYmVybmF0ZS1jb21taXRzIGRpZ2VzdC4uLiINCj4NCj4NCj5Ub2RheSdzIFRvcGlj czoNCj4NCj4gICAxLiAobm8gc3ViamVjdCkgKE5vdmlhciBTYmFzdGlhbikNCj4NCj4tLV9fLS1f Xy0tDQo+DQo+TWVzc2FnZTogMQ0KPkRhdGU6IE1vbiwgMjAgTWFyIDIwMDYgMDk6MDg6MzEgKzA3 MDANCj5Gcm9tOiAiTm92aWFyIFNiYXN0aWFuIiA8bm92aWFyc0BnbWFpbC5jb20+DQo+VG86IGhp YmVybmF0ZS1jb21taXRzQGxpc3RzLnNvdXJjZWZvcmdlLm5ldA0KPlN1YmplY3Q6IFtIaWJlcm5h dGUtY29tbWl0c10gKG5vIHN1YmplY3QpDQo+DQo+LS0tLS0tPV9QYXJ0Xzg2NjZfMjA3NTE5MjAu MTE0MjgyMDUxMTUzMA0KPkNvbnRlbnQtVHlwZTogdGV4dC9wbGFpbjsgY2hhcnNldD1JU08tODg1 OS0xDQo+Q29udGVudC1UcmFuc2Zlci1FbmNvZGluZzogcXVvdGVkLXByaW50YWJsZQ0KPkNvbnRl bnQtRGlzcG9zaXRpb246IGlubGluZQ0KPg0KPg0KPg0KPi0tLS0tLT1fUGFydF84NjY2XzIwNzUx OTIwLjExNDI4MjA1MTE1MzANCj5Db250ZW50LVR5cGU6IHRleHQvaHRtbDsgY2hhcnNldD1JU08t ODg1OS0xDQo+Q29udGVudC1UcmFuc2Zlci1FbmNvZGluZzogcXVvdGVkLXByaW50YWJsZQ0KPkNv bnRlbnQtRGlzcG9zaXRpb246IGlubGluZQ0KPg0KPg0KPg0KPi0tLS0tLT1fUGFydF84NjY2XzIw NzUxOTIwLjExNDI4MjA1MTE1MzAtLQ0KPg0KPg0KPg0KPi0tX18tLV9fLS0NCj4NCj5fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXw0KPmhpYmVybmF0ZS1jb21t aXRzIG1haWxpbmcgbGlzdA0KPmhpYmVybmF0ZS1jb21taXRzQGxpc3RzLnNvdXJjZWZvcmdlLm5l dA0KPmh0dHBzOi8vbGlzdHMuc291cmNlZm9yZ2UubmV0L2xpc3RzL2xpc3RpbmZvL2hpYmVybmF0 ZS1jb21taXRzDQo+DQo+DQo+RW5kIG9mIGhpYmVybmF0ZS1jb21taXRzIERpZ2VzdA0KPg0KDQo9 ID0gPSA9ID0gPSA9ID0gPSA9ID0gPSA9ID0gPSA9ID0gPSA9ID0NCgkJCQ0KDQqhoaGhoaGhoaGh oaGhoaGh1sINCsDxo6ENCiANCgkJCQkgDQqhoaGhoaGhoaGhoaGhoaGhcHRtYW4NCqGhoaGhoaGh oaGhoaGhoaFwdG1hbkAxMjYuY29tDQqhoaGhoaGhoaGhoaGhoaGhoaGhoTIwMDYtMDMtMjcNCg0K |
|
From: <hib...@li...> - 2006-03-24 19:20:08
|
Author: max...@jb...
Date: 2006-03-24 14:20:01 -0500 (Fri, 24 Mar 2006)
New Revision: 9682
Modified:
trunk/HibernateExt/tools/src/java/org/hibernate/tool/hbm2x/ArtifactCollector.java
trunk/HibernateExt/tools/src/java/org/hibernate/tool/hbm2x/HibernateConfigurationExporter.java
trunk/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/hbm2hbmxml/Basic.hbm.xml
Log:
NPe fix
Modified: trunk/HibernateExt/tools/src/java/org/hibernate/tool/hbm2x/ArtifactCollector.java
===================================================================
--- trunk/HibernateExt/tools/src/java/org/hibernate/tool/hbm2x/ArtifactCollector.java 2006-03-24 18:10:04 UTC (rev 9681)
+++ trunk/HibernateExt/tools/src/java/org/hibernate/tool/hbm2x/ArtifactCollector.java 2006-03-24 19:20:01 UTC (rev 9682)
@@ -23,7 +23,7 @@
/**
* Called to inform that a file has been created by the exporter.
*/
- public void addFile(File file, String type) {
+ public void addFile(File file, String type) {
List existing = (List) files.get(type);
if(existing==null) {
existing = new ArrayList();
Modified: trunk/HibernateExt/tools/src/java/org/hibernate/tool/hbm2x/HibernateConfigurationExporter.java
===================================================================
--- trunk/HibernateExt/tools/src/java/org/hibernate/tool/hbm2x/HibernateConfigurationExporter.java 2006-03-24 18:10:04 UTC (rev 9681)
+++ trunk/HibernateExt/tools/src/java/org/hibernate/tool/hbm2x/HibernateConfigurationExporter.java 2006-03-24 19:20:01 UTC (rev 9682)
@@ -64,12 +64,13 @@
file = new File(getOutputDirectory(), "hibernate.cfg.xml");
getTemplateHelper().ensureExistence(file);
pw = new PrintWriter(new FileWriter(file) );
+ getArtifactCollector().addFile(file, "cfg.xml");
}
else {
pw = new PrintWriter(output);
}
- getArtifactCollector().addFile(file, "cfg.xml");
+
pw.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<!DOCTYPE hibernate-configuration PUBLIC\r\n" +
" \"-//Hibernate/Hibernate Configuration DTD 3.0//EN\"\r\n" +
Modified: trunk/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/hbm2hbmxml/Basic.hbm.xml
===================================================================
--- trunk/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/hbm2hbmxml/Basic.hbm.xml 2006-03-24 18:10:04 UTC (rev 9681)
+++ trunk/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/hbm2hbmxml/Basic.hbm.xml 2006-03-24 19:20:01 UTC (rev 9682)
@@ -14,7 +14,7 @@
<id name="basicId"
length="10"
- type="string"
+
unsaved-value="null"
>
<generator class="org.hibernate.id.TableHiLoGenerator">
|
|
From: <hib...@li...> - 2006-03-24 18:10:12
|
Author: ste...@jb...
Date: 2006-03-24 13:10:04 -0500 (Fri, 24 Mar 2006)
New Revision: 9681
Added:
trunk/Hibernate3/src/org/hibernate/id/insert/
trunk/Hibernate3/src/org/hibernate/id/insert/AbstractReturningDelegate.java
trunk/Hibernate3/src/org/hibernate/id/insert/AbstractSelectingDelegate.java
trunk/Hibernate3/src/org/hibernate/id/insert/Binder.java
trunk/Hibernate3/src/org/hibernate/id/insert/IdentifierGeneratingInsert.java
trunk/Hibernate3/src/org/hibernate/id/insert/InsertGeneratedIdentifierDelegate.java
trunk/Hibernate3/src/org/hibernate/id/insert/InsertSelectIdentityInsert.java
Modified:
trunk/Hibernate3/src/org/hibernate/id/AbstractPostInsertGenerator.java
trunk/Hibernate3/src/org/hibernate/id/IdentityGenerator.java
trunk/Hibernate3/src/org/hibernate/id/PostInsertIdentifierGenerator.java
trunk/Hibernate3/src/org/hibernate/id/PostInsertIdentityPersister.java
trunk/Hibernate3/src/org/hibernate/id/SelectGenerator.java
trunk/Hibernate3/src/org/hibernate/persister/entity/AbstractEntityPersister.java
trunk/Hibernate3/src/org/hibernate/sql/Insert.java
Log:
HHH-1590 : changed how PostInsertIdentifierGenerators are handled
Modified: trunk/Hibernate3/src/org/hibernate/id/AbstractPostInsertGenerator.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/id/AbstractPostInsertGenerator.java 2006-03-22 23:47:31 UTC (rev 9680)
+++ trunk/Hibernate3/src/org/hibernate/id/AbstractPostInsertGenerator.java 2006-03-24 18:10:04 UTC (rev 9681)
@@ -2,65 +2,14 @@
package org.hibernate.id;
import java.io.Serializable;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import org.hibernate.HibernateException;
import org.hibernate.engine.SessionImplementor;
-import org.hibernate.exception.JDBCExceptionHelper;
-import org.hibernate.pretty.MessageHelper;
/**
* @author Gavin King
*/
public abstract class AbstractPostInsertGenerator implements PostInsertIdentifierGenerator{
-
public Serializable generate(SessionImplementor s, Object obj) {
return IdentifierGeneratorFactory.POST_INSERT_INDICATOR;
}
-
- protected abstract String getSQL(PostInsertIdentityPersister persister);
-
- protected void bindParameters(SessionImplementor session, PreparedStatement ps, Object object, PostInsertIdentityPersister persister)
- throws SQLException {}
-
- protected abstract Serializable getResult(SessionImplementor session, ResultSet rs, Object object, PostInsertIdentityPersister persister)
- throws SQLException;
-
- public Serializable getGenerated(SessionImplementor session, Object object, PostInsertIdentityPersister persister)
- throws HibernateException {
-
- final String sql = getSQL(persister);
-
- try {
-
- //fetch the generated id in a separate query
- PreparedStatement idSelect = session.getBatcher().prepareStatement(sql);
- try {
- bindParameters(session, idSelect, object, persister);
- ResultSet rs = idSelect.executeQuery();
- try {
- return getResult(session, rs, object, persister);
- }
- finally {
- rs.close();
- }
- }
- finally {
- session.getBatcher().closeStatement(idSelect);
- }
-
- }
- catch ( SQLException sqle ) {
- throw JDBCExceptionHelper.convert(
- session.getFactory().getSQLExceptionConverter(),
- sqle,
- "could not insert: " + MessageHelper.infoString( persister ),
- sql
- );
- }
-
- }
-
}
Modified: trunk/Hibernate3/src/org/hibernate/id/IdentityGenerator.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/id/IdentityGenerator.java 2006-03-22 23:47:31 UTC (rev 9680)
+++ trunk/Hibernate3/src/org/hibernate/id/IdentityGenerator.java 2006-03-24 18:10:04 UTC (rev 9681)
@@ -4,11 +4,22 @@
import java.io.Serializable;
import java.sql.ResultSet;
import java.sql.SQLException;
+import java.sql.PreparedStatement;
import org.hibernate.engine.SessionImplementor;
+import org.hibernate.id.insert.InsertGeneratedIdentifierDelegate;
+import org.hibernate.id.insert.IdentifierGeneratingInsert;
+import org.hibernate.id.insert.AbstractSelectingDelegate;
+import org.hibernate.id.insert.AbstractReturningDelegate;
+import org.hibernate.id.insert.InsertSelectIdentityInsert;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.HibernateException;
+import org.hibernate.AssertionFailure;
+import org.hibernate.util.GetGeneratedKeysHelper;
/**
+ * A generator for use with ANSI-SQL IDENTITY columns used as the primary key.
* The IdentityGenerator for autoincrement/identity key generation.
* <br><br>
* Indicates to the <tt>Session</tt> that identity (ie. identity/autoincrement
@@ -18,18 +29,133 @@
*/
public class IdentityGenerator extends AbstractPostInsertGenerator {
- protected String getSQL(PostInsertIdentityPersister persister) {
- return persister.getIdentitySelectString();
+ public InsertGeneratedIdentifierDelegate getInsertGeneratedIdentifierDelegate(
+ PostInsertIdentityPersister persister,
+ Dialect dialect,
+ boolean isGetGeneratedKeysEnabled) throws HibernateException {
+ if ( isGetGeneratedKeysEnabled ) {
+ return new GetGeneratedKeysDelegate( persister, dialect );
+ }
+ else if ( dialect.supportsInsertSelectIdentity() ) {
+ return new InsertSelectDelegate( persister, dialect );
+ }
+ else {
+ return new BasicDelegate( persister, dialect );
+ }
}
-
- protected Serializable getResult(SessionImplementor session, ResultSet rs, Object object, PostInsertIdentityPersister persister)
- throws SQLException {
- return IdentifierGeneratorFactory.getGeneratedIdentity( rs, persister.getIdentifierType() );
+
+ /**
+ * Delegate for dealing with IDENTITY columns using JDBC3 getGeneratedKeys
+ */
+ public static class GetGeneratedKeysDelegate
+ extends AbstractReturningDelegate
+ implements InsertGeneratedIdentifierDelegate {
+ private final PostInsertIdentityPersister persister;
+ private final Dialect dialect;
+
+ public GetGeneratedKeysDelegate(PostInsertIdentityPersister persister, Dialect dialect) {
+ super( persister );
+ this.persister = persister;
+ this.dialect = dialect;
+ }
+
+ public IdentifierGeneratingInsert prepareIdentifierGeneratingInsert() {
+ IdentifierGeneratingInsert insert = new IdentifierGeneratingInsert( dialect );
+ insert.addIdentityColumn( persister.getRootTableKeyColumnNames()[0] );
+ return insert;
+ }
+
+ protected PreparedStatement prepare(String insertSQL, SessionImplementor session) throws SQLException {
+ return session.getBatcher().prepareStatement( insertSQL, true );
+ }
+
+ public Serializable executeAndExtract(PreparedStatement insert) throws SQLException {
+ insert.executeUpdate();
+ return IdentifierGeneratorFactory.getGeneratedIdentity(
+ GetGeneratedKeysHelper.getGeneratedKey( insert ),
+ persister.getIdentifierType()
+ );
+ }
}
-}
+ /**
+ * Delegate for dealing with IDENTITY columns where the dialect supports returning
+ * the generated IDENTITY value directly from the insert statement.
+ */
+ public static class InsertSelectDelegate
+ extends AbstractReturningDelegate
+ implements InsertGeneratedIdentifierDelegate {
+ private final PostInsertIdentityPersister persister;
+ private final Dialect dialect;
+ public InsertSelectDelegate(PostInsertIdentityPersister persister, Dialect dialect) {
+ super( persister );
+ this.persister = persister;
+ this.dialect = dialect;
+ }
+ public IdentifierGeneratingInsert prepareIdentifierGeneratingInsert() {
+ InsertSelectIdentityInsert insert = new InsertSelectIdentityInsert( dialect );
+ insert.addIdentityColumn( persister.getRootTableKeyColumnNames()[0] );
+ return insert;
+ }
+ protected PreparedStatement prepare(String insertSQL, SessionImplementor session) throws SQLException {
+ return session.getBatcher().prepareStatement( insertSQL, false );
+ }
+ public Serializable executeAndExtract(PreparedStatement insert) throws SQLException {
+ if ( !insert.execute() ) {
+ while ( !insert.getMoreResults() && insert.getUpdateCount() != -1 ) {
+ // do nothing until we hit the rsult set containing the generated id
+ }
+ }
+ ResultSet rs = insert.getResultSet();
+ try {
+ return IdentifierGeneratorFactory.getGeneratedIdentity( rs, persister.getIdentifierType() );
+ }
+ finally {
+ rs.close();
+ }
+ }
+ public Serializable determineGeneratedIdentifier(SessionImplementor session, Object entity) {
+ throw new AssertionFailure( "insert statement returns generated value" );
+ }
+ }
+
+ /**
+ * Delegate for dealing with IDENTITY columns where the dialect requires an
+ * additional command execution to retrieve the generated IDENTITY value
+ */
+ public static class BasicDelegate
+ extends AbstractSelectingDelegate
+ implements InsertGeneratedIdentifierDelegate {
+ private final PostInsertIdentityPersister persister;
+ private final Dialect dialect;
+
+ public BasicDelegate(PostInsertIdentityPersister persister, Dialect dialect) {
+ super( persister );
+ this.persister = persister;
+ this.dialect = dialect;
+ }
+
+ public IdentifierGeneratingInsert prepareIdentifierGeneratingInsert() {
+ IdentifierGeneratingInsert insert = new IdentifierGeneratingInsert( dialect );
+ insert.addIdentityColumn( persister.getRootTableKeyColumnNames()[0] );
+ return insert;
+ }
+
+ protected String getSelectSQL() {
+ return persister.getIdentitySelectString();
+ }
+
+ protected Serializable getResult(
+ SessionImplementor session,
+ ResultSet rs,
+ Object object) throws SQLException {
+ return IdentifierGeneratorFactory.getGeneratedIdentity( rs, persister.getIdentifierType() );
+ }
+ }
+
+}
Modified: trunk/Hibernate3/src/org/hibernate/id/PostInsertIdentifierGenerator.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/id/PostInsertIdentifierGenerator.java 2006-03-22 23:47:31 UTC (rev 9680)
+++ trunk/Hibernate3/src/org/hibernate/id/PostInsertIdentifierGenerator.java 2006-03-24 18:10:04 UTC (rev 9681)
@@ -1,15 +1,16 @@
//$Id$
package org.hibernate.id;
-import java.io.Serializable;
-
import org.hibernate.HibernateException;
-import org.hibernate.engine.SessionImplementor;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.id.insert.InsertGeneratedIdentifierDelegate;
/**
* @author Gavin King
*/
public interface PostInsertIdentifierGenerator extends IdentifierGenerator {
- public Serializable getGenerated(SessionImplementor session, Object object, PostInsertIdentityPersister persister)
- throws HibernateException;
+ public InsertGeneratedIdentifierDelegate getInsertGeneratedIdentifierDelegate(
+ PostInsertIdentityPersister persister,
+ Dialect dialect,
+ boolean isGetGeneratedKeysEnabled) throws HibernateException;
}
Modified: trunk/Hibernate3/src/org/hibernate/id/PostInsertIdentityPersister.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/id/PostInsertIdentityPersister.java 2006-03-22 23:47:31 UTC (rev 9680)
+++ trunk/Hibernate3/src/org/hibernate/id/PostInsertIdentityPersister.java 2006-03-24 18:10:04 UTC (rev 9681)
@@ -6,12 +6,32 @@
/**
* A persister that may have an identity assigned by execution of
* a SQL <tt>INSERT</tt>.
+ *
* @author Gavin King
*/
public interface PostInsertIdentityPersister extends EntityPersister {
-
+ /**
+ * Get a SQL select string that performs a select based on a unique
+ * key determined by the given property name).
+ *
+ * @param propertyName The name of the property which maps to the
+ * column(s) to use in the select statement restriction.
+ * @return The SQL select string
+ */
public String getSelectByUniqueKeyString(String propertyName);
+
+ /**
+ * Get the database-specific SQL command to retrieve the last
+ * generated IDENTITY value.
+ *
+ * @return The SQL command string
+ */
public String getIdentitySelectString();
+
+ /**
+ * The names of the primary key columns in the root table.
+ *
+ * @return The primary key column names.
+ */
public String[] getRootTableKeyColumnNames();
-
}
Modified: trunk/Hibernate3/src/org/hibernate/id/SelectGenerator.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/id/SelectGenerator.java 2006-03-22 23:47:31 UTC (rev 9680)
+++ trunk/Hibernate3/src/org/hibernate/id/SelectGenerator.java 2006-03-24 18:10:04 UTC (rev 9681)
@@ -8,92 +8,129 @@
import java.util.Properties;
import org.hibernate.MappingException;
+import org.hibernate.HibernateException;
+import org.hibernate.id.insert.InsertGeneratedIdentifierDelegate;
+import org.hibernate.id.insert.IdentifierGeneratingInsert;
+import org.hibernate.id.insert.AbstractSelectingDelegate;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.type.Type;
/**
- * An IdentityGenerator that selects the inserted row, to determine
- * an identifier value assigned by the database. The correct row is
- * located using a unique key.
- * <br><br>
- * One mapping parameter is required: key.
+ * A generator that selects the just inserted row to determine the identifier
+ * value assigned by the database. The correct row is located using a unique
+ * key.
+ * <p/>
+ * One mapping parameter is required: key (unless a natural-id is defined in the mapping).
*
* @author Gavin King
*/
public class SelectGenerator extends AbstractPostInsertGenerator implements Configurable {
private String uniqueKeyPropertyName;
- private Type idType;
- private String entityName;
public void configure(Type type, Properties params, Dialect d) throws MappingException {
- uniqueKeyPropertyName = params.getProperty("key");
- entityName = params.getProperty(ENTITY_NAME);
- this.idType = type;
+ uniqueKeyPropertyName = params.getProperty( "key" );
}
-
- protected String getSQL(PostInsertIdentityPersister persister) {
- if ( entityName == null ) {
- entityName = persister.getEntityName();
+
+ public InsertGeneratedIdentifierDelegate getInsertGeneratedIdentifierDelegate(
+ PostInsertIdentityPersister persister,
+ Dialect dialect,
+ boolean isGetGeneratedKeysEnabled) throws HibernateException {
+ return new SelectGeneratorDelegate( persister, dialect, uniqueKeyPropertyName );
+ }
+
+ private static String determineNameOfPropertyToUse(PostInsertIdentityPersister persister, String supplied) {
+ if ( supplied != null ) {
+ return supplied;
}
- if ( uniqueKeyPropertyName == null ) {
- int[] naturalIdPropertyIndices = persister.getNaturalIdentifierProperties();
- if ( naturalIdPropertyIndices == null ){
- throw new IdentifierGenerationException(
- "no natural-id property defined; need to specify [key] in " +
- "generator parameters"
- );
- }
- if ( naturalIdPropertyIndices.length > 1 ) {
- throw new IdentifierGenerationException(
- "select generator does not currently support composite " +
- "natural-id properties; need to specify [key] in generator parameters"
- );
- }
- if ( persister.getPropertyInsertGeneration() [ naturalIdPropertyIndices[0] ] ) {
- throw new IdentifierGenerationException(
- "natural-id also defined as insert-generated; need to specify [key] " +
- "in generator parameters"
- );
- }
- uniqueKeyPropertyName = persister.getPropertyNames() [ naturalIdPropertyIndices[0] ];
+ int[] naturalIdPropertyIndices = persister.getNaturalIdentifierProperties();
+ if ( naturalIdPropertyIndices == null ){
+ throw new IdentifierGenerationException(
+ "no natural-id property defined; need to specify [key] in " +
+ "generator parameters"
+ );
}
- return persister.getSelectByUniqueKeyString( uniqueKeyPropertyName );
+ if ( naturalIdPropertyIndices.length > 1 ) {
+ throw new IdentifierGenerationException(
+ "select generator does not currently support composite " +
+ "natural-id properties; need to specify [key] in generator parameters"
+ );
+ }
+ if ( persister.getPropertyInsertGeneration() [ naturalIdPropertyIndices[0] ] ) {
+ throw new IdentifierGenerationException(
+ "natural-id also defined as insert-generated; need to specify [key] " +
+ "in generator parameters"
+ );
+ }
+ return persister.getPropertyNames() [ naturalIdPropertyIndices[0] ];
}
- protected void bindParameters(
- SessionImplementor session,
- PreparedStatement ps,
- Object object,
- PostInsertIdentityPersister persister) throws SQLException {
- Type uniqueKeyPropertyType = session.getFactory()
- .getClassMetadata( entityName )
- .getPropertyType( uniqueKeyPropertyName );
- Object uniqueKeyValue = persister.getPropertyValue(
- object,
- uniqueKeyPropertyName,
- session.getEntityMode()
- );
- uniqueKeyPropertyType.nullSafeSet( ps, uniqueKeyValue, 1, session );
- }
- protected Serializable getResult(
- SessionImplementor session,
- ResultSet rs,
- Object object,
- PostInsertIdentityPersister persister) throws SQLException {
- if ( !rs.next() ) {
- throw new IdentifierGenerationException(
- "the inserted row could not be located by the unique key: " +
- uniqueKeyPropertyName
+ /**
+ * The delegate for the select generation strategy.
+ */
+ public static class SelectGeneratorDelegate
+ extends AbstractSelectingDelegate
+ implements InsertGeneratedIdentifierDelegate {
+ private final PostInsertIdentityPersister persister;
+ private final Dialect dialect;
+
+ private final String uniqueKeyPropertyName;
+ private final Type uniqueKeyType;
+ private final Type idType;
+
+ private final String idSelectString;
+
+ private SelectGeneratorDelegate(
+ PostInsertIdentityPersister persister,
+ Dialect dialect,
+ String suppliedUniqueKeyPropertyName) {
+ super( persister );
+ this.persister = persister;
+ this.dialect = dialect;
+ this.uniqueKeyPropertyName = determineNameOfPropertyToUse( persister, suppliedUniqueKeyPropertyName );
+
+ idSelectString = persister.getSelectByUniqueKeyString( uniqueKeyPropertyName );
+ uniqueKeyType = persister.getPropertyType( uniqueKeyPropertyName );
+ idType = persister.getIdentifierType();
+ }
+
+ public IdentifierGeneratingInsert prepareIdentifierGeneratingInsert() {
+ return new IdentifierGeneratingInsert( dialect );
+ }
+
+
+ // AbstractSelectingDelegate impl ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ protected String getSelectSQL() {
+ return idSelectString;
+ }
+
+ protected void bindParameters(
+ SessionImplementor session,
+ PreparedStatement ps,
+ Object entity) throws SQLException {
+ Object uniqueKeyValue = persister.getPropertyValue( entity, uniqueKeyPropertyName, session.getEntityMode() );
+ uniqueKeyType.nullSafeSet( ps, uniqueKeyValue, 1, session );
+ }
+
+ protected Serializable getResult(
+ SessionImplementor session,
+ ResultSet rs,
+ Object entity) throws SQLException {
+ if ( !rs.next() ) {
+ throw new IdentifierGenerationException(
+ "the inserted row could not be located by the unique key: " +
+ uniqueKeyPropertyName
+ );
+ }
+ return ( Serializable ) idType.nullSafeGet(
+ rs,
+ persister.getRootTableKeyColumnNames(),
+ session,
+ entity
);
}
- return ( Serializable ) idType.nullSafeGet(
- rs,
- persister.getRootTableKeyColumnNames(),
- session,
- object
- );
}
}
Added: trunk/Hibernate3/src/org/hibernate/id/insert/AbstractReturningDelegate.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/id/insert/AbstractReturningDelegate.java 2006-03-22 23:47:31 UTC (rev 9680)
+++ trunk/Hibernate3/src/org/hibernate/id/insert/AbstractReturningDelegate.java 2006-03-24 18:10:04 UTC (rev 9681)
@@ -0,0 +1,52 @@
+package org.hibernate.id.insert;
+
+import org.hibernate.id.PostInsertIdentityPersister;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.exception.JDBCExceptionHelper;
+import org.hibernate.pretty.MessageHelper;
+
+import java.io.Serializable;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
+/**
+ * Abstract InsertGeneratedIdentifierDelegate implementation where the
+ * underlying strategy causes the enerated identitifer to be returned as an
+ * effect of performing the insert statement. Thus, there is no need for an
+ * additional sql statement to determine the generated identitifer.
+ *
+ * @author Steve Ebersole
+ */
+public abstract class AbstractReturningDelegate implements InsertGeneratedIdentifierDelegate {
+ private final PostInsertIdentityPersister persister;
+
+ public AbstractReturningDelegate(PostInsertIdentityPersister persister) {
+ this.persister = persister;
+ }
+
+ public final Serializable performInsert(String insertSQL, SessionImplementor session, Binder binder) {
+ try {
+ // prepare and execute the insert
+ PreparedStatement insert = prepare( insertSQL, session );
+ try {
+ binder.bindValues( insert );
+ return executeAndExtract( insert );
+ }
+ finally {
+ session.getBatcher().closeStatement( insert );
+ }
+ }
+ catch ( SQLException sqle ) {
+ throw JDBCExceptionHelper.convert(
+ session.getFactory().getSQLExceptionConverter(),
+ sqle,
+ "could not insert: " + MessageHelper.infoString( persister ),
+ insertSQL
+ );
+ }
+ }
+
+ protected abstract PreparedStatement prepare(String insertSQL, SessionImplementor session) throws SQLException;
+
+ protected abstract Serializable executeAndExtract(PreparedStatement insert) throws SQLException;
+}
Added: trunk/Hibernate3/src/org/hibernate/id/insert/AbstractSelectingDelegate.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/id/insert/AbstractSelectingDelegate.java 2006-03-22 23:47:31 UTC (rev 9680)
+++ trunk/Hibernate3/src/org/hibernate/id/insert/AbstractSelectingDelegate.java 2006-03-24 18:10:04 UTC (rev 9681)
@@ -0,0 +1,113 @@
+package org.hibernate.id.insert;
+
+import org.hibernate.exception.JDBCExceptionHelper;
+import org.hibernate.pretty.MessageHelper;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.id.PostInsertIdentityPersister;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.sql.ResultSet;
+import java.io.Serializable;
+
+/**
+ * Abstract InsertGeneratedIdentifierDelegate implementation where the
+ * underlying strategy requires an subsequent select after the insert
+ * to determine the generated identifier.
+ *
+ * @author Steve Ebersole
+ */
+public abstract class AbstractSelectingDelegate implements InsertGeneratedIdentifierDelegate {
+ private final PostInsertIdentityPersister persister;
+
+ protected AbstractSelectingDelegate(PostInsertIdentityPersister persister) {
+ this.persister = persister;
+ }
+
+ public final Serializable performInsert(String insertSQL, SessionImplementor session, Binder binder) {
+ try {
+ // prepare and execute the insert
+ PreparedStatement insert = session.getBatcher().prepareStatement( insertSQL, false );
+ try {
+ binder.bindValues( insert );
+ insert.executeUpdate();
+ }
+ finally {
+ session.getBatcher().closeStatement( insert );
+ }
+ }
+ catch ( SQLException sqle ) {
+ throw JDBCExceptionHelper.convert(
+ session.getFactory().getSQLExceptionConverter(),
+ sqle,
+ "could not insert: " + MessageHelper.infoString( persister ),
+ insertSQL
+ );
+ }
+
+ final String selectSQL = getSelectSQL();
+
+ try {
+ //fetch the generated id in a separate query
+ PreparedStatement idSelect = session.getBatcher().prepareStatement( selectSQL );
+ try {
+ bindParameters( session, idSelect, binder.getEntity() );
+ ResultSet rs = idSelect.executeQuery();
+ try {
+ return getResult( session, rs, binder.getEntity() );
+ }
+ finally {
+ rs.close();
+ }
+ }
+ finally {
+ session.getBatcher().closeStatement( idSelect );
+ }
+
+ }
+ catch ( SQLException sqle ) {
+ throw JDBCExceptionHelper.convert(
+ session.getFactory().getSQLExceptionConverter(),
+ sqle,
+ "could not retrieve generated id after insert: " + MessageHelper.infoString( persister ),
+ insertSQL
+ );
+ }
+ }
+
+ /**
+ * Get the SQL statement to be used to retrieve generated key values.
+ *
+ * @return The SQL command string
+ */
+ protected abstract String getSelectSQL();
+
+ /**
+ * Bind any required parameter values into the SQL command {@link #getSelectSQL}.
+ *
+ * @param session The session
+ * @param ps The prepared {@link #getSelectSQL SQL} command
+ * @param entity The entity being saved.
+ * @throws SQLException
+ */
+ protected void bindParameters(
+ SessionImplementor session,
+ PreparedStatement ps,
+ Object entity) throws SQLException {
+ }
+
+ /**
+ * Extract the generated key value from the given result set.
+ *
+ * @param session The session
+ * @param rs The result set containing the generated primay key values.
+ * @param entity The entity being saved.
+ * @return The generated identifier
+ * @throws SQLException
+ */
+ protected abstract Serializable getResult(
+ SessionImplementor session,
+ ResultSet rs,
+ Object entity) throws SQLException;
+
+}
Added: trunk/Hibernate3/src/org/hibernate/id/insert/Binder.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/id/insert/Binder.java 2006-03-22 23:47:31 UTC (rev 9680)
+++ trunk/Hibernate3/src/org/hibernate/id/insert/Binder.java 2006-03-24 18:10:04 UTC (rev 9681)
@@ -0,0 +1,12 @@
+package org.hibernate.id.insert;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
+/**
+ * @author Steve Ebersole
+ */
+public interface Binder {
+ public void bindValues(PreparedStatement ps) throws SQLException;
+ public Object getEntity();
+}
Added: trunk/Hibernate3/src/org/hibernate/id/insert/IdentifierGeneratingInsert.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/id/insert/IdentifierGeneratingInsert.java 2006-03-22 23:47:31 UTC (rev 9680)
+++ trunk/Hibernate3/src/org/hibernate/id/insert/IdentifierGeneratingInsert.java 2006-03-24 18:10:04 UTC (rev 9681)
@@ -0,0 +1,17 @@
+package org.hibernate.id.insert;
+
+import org.hibernate.sql.Insert;
+import org.hibernate.dialect.Dialect;
+
+/**
+ * Nothing more than a distinguishing subclass of Insert used to indicate
+ * intent. Some subclasses of this also provided some additional
+ * functionality or semantic to the genernated SQL statement string.
+ *
+ * @author Steve Ebersole
+ */
+public class IdentifierGeneratingInsert extends Insert {
+ public IdentifierGeneratingInsert(Dialect dialect) {
+ super( dialect );
+ }
+}
Added: trunk/Hibernate3/src/org/hibernate/id/insert/InsertGeneratedIdentifierDelegate.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/id/insert/InsertGeneratedIdentifierDelegate.java 2006-03-22 23:47:31 UTC (rev 9680)
+++ trunk/Hibernate3/src/org/hibernate/id/insert/InsertGeneratedIdentifierDelegate.java 2006-03-24 18:10:04 UTC (rev 9681)
@@ -0,0 +1,39 @@
+package org.hibernate.id.insert;
+
+import org.hibernate.engine.SessionImplementor;
+
+import java.io.Serializable;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
+/**
+ * Responsible for handling delegation relating to variants in how
+ * insert-generated-identifier generator strategies dictate processing:<ul>
+ * <li>building the sql insert statement
+ * <li>determination of the generated identifier value
+ * </ul>
+ *
+ * @author Steve Ebersole
+ */
+public interface InsertGeneratedIdentifierDelegate {
+
+ /**
+ * Build a {@link org.hibernate.sql.Insert} specific to the delegate's mode
+ * of handling generated key values.
+ *
+ * @return The insert object.
+ */
+ public IdentifierGeneratingInsert prepareIdentifierGeneratingInsert();
+
+ /**
+ * Perform the indicated insert SQL statement and determine the identifier value
+ * generated.
+ *
+ * @param insertSQL
+ * @param session
+ * @param binder
+ * @return The generated identifier value.
+ */
+ public Serializable performInsert(String insertSQL, SessionImplementor session, Binder binder);
+
+}
Added: trunk/Hibernate3/src/org/hibernate/id/insert/InsertSelectIdentityInsert.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/id/insert/InsertSelectIdentityInsert.java 2006-03-22 23:47:31 UTC (rev 9680)
+++ trunk/Hibernate3/src/org/hibernate/id/insert/InsertSelectIdentityInsert.java 2006-03-24 18:10:04 UTC (rev 9681)
@@ -0,0 +1,20 @@
+package org.hibernate.id.insert;
+
+import org.hibernate.dialect.Dialect;
+
+/**
+ * Specialized IdentifierGeneratingInsert which appends the database
+ * specific clause which signifies to return generated IDENTITY values
+ * to the end of the insert statement.
+ *
+ * @author Steve Ebersole
+ */
+public class InsertSelectIdentityInsert extends IdentifierGeneratingInsert {
+ public InsertSelectIdentityInsert(Dialect dialect) {
+ super( dialect );
+ }
+
+ public String toStatementString() {
+ return getDialect().appendIdentitySelectToInsert( super.toStatementString() );
+ }
+}
Modified: trunk/Hibernate3/src/org/hibernate/persister/entity/AbstractEntityPersister.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/persister/entity/AbstractEntityPersister.java 2006-03-22 23:47:31 UTC (rev 9680)
+++ trunk/Hibernate3/src/org/hibernate/persister/entity/AbstractEntityPersister.java 2006-03-24 18:10:04 UTC (rev 9681)
@@ -27,7 +27,6 @@
import org.hibernate.QueryException;
import org.hibernate.StaleObjectStateException;
import org.hibernate.dialect.lock.LockingStrategy;
-import org.hibernate.dialect.lock.SelectLockingStrategy;
import org.hibernate.cache.CacheConcurrencyStrategy;
import org.hibernate.cache.CacheKey;
import org.hibernate.cache.entry.CacheEntry;
@@ -43,9 +42,10 @@
import org.hibernate.engine.Versioning;
import org.hibernate.exception.JDBCExceptionHelper;
import org.hibernate.id.IdentifierGenerator;
-import org.hibernate.id.IdentifierGeneratorFactory;
import org.hibernate.id.PostInsertIdentifierGenerator;
import org.hibernate.id.PostInsertIdentityPersister;
+import org.hibernate.id.insert.InsertGeneratedIdentifierDelegate;
+import org.hibernate.id.insert.Binder;
import org.hibernate.intercept.LazyPropertyInitializer;
import org.hibernate.intercept.FieldInterceptionHelper;
import org.hibernate.intercept.FieldInterceptor;
@@ -82,7 +82,6 @@
import org.hibernate.util.ArrayHelper;
import org.hibernate.util.CollectionHelper;
import org.hibernate.util.FilterHelper;
-import org.hibernate.util.GetGeneratedKeysHelper;
import org.hibernate.util.StringHelper;
/**
@@ -197,6 +196,8 @@
protected String[] customSQLUpdate;
protected String[] customSQLDelete;
+ private InsertGeneratedIdentifierDelegate identityDelegate;
+
private boolean[] tableHasColumns;
private final String loaderName;
@@ -1289,93 +1290,6 @@
return getRootTableKeyColumnNames();
}
-// /**
-// * Generate the SQL that pessimistic locks a row by id (and version)
-// */
-// protected String generateLockString(LockMode lockMode) {
-// SimpleSelect select = new SimpleSelect( getFactory().getDialect() )
-// .setLockMode( lockMode )
-// .setTableName( getVersionedTableName() )
-// .addColumn( rootTableKeyColumnNames[0] )
-// .addCondition( rootTableKeyColumnNames, "=?" );
-// if ( isVersioned() ) {
-// select.addCondition( getVersionColumnName(), "=?" );
-// }
-// if ( getFactory().getSettings().isCommentsEnabled() ) {
-// select.setComment( "lock " + getEntityName() );
-// }
-// return select.toStatementString();
-// }
-//
-// protected void initLockers() {
-// lockers.put( LockMode.READ, generateLockString( LockMode.READ ) );
-// lockers.put( LockMode.UPGRADE, generateLockString( LockMode.UPGRADE ) );
-// lockers.put( LockMode.UPGRADE_NOWAIT, generateLockString( LockMode.UPGRADE_NOWAIT ) );
-// }
-//
-// private String getLockString(LockMode lockMode) {
-// return ( String ) lockers.get( lockMode );
-// }
-//
-// /**
-// * Do a version check
-// */
-// public void lock(Serializable id, Object version, Object object, LockMode lockMode, SessionImplementor session)
-// throws HibernateException {
-//
-// if ( lockMode != LockMode.NONE ) {
-//
-// if ( log.isTraceEnabled() ) {
-// log.trace( "Locking entity: " + MessageHelper.infoString( this, id, getFactory() ) );
-// if ( isVersioned() ) {
-// log.trace( "Version: " + version );
-// }
-// }
-//
-// final String sql = getLockString( lockMode );
-//
-// try {
-//
-// PreparedStatement st = session.getBatcher().prepareSelectStatement( sql );
-// try {
-// getIdentifierType().nullSafeSet( st, id, 1, session );
-// if ( isVersioned() ) {
-// getVersionType().nullSafeSet( st, version, getIdentifierColumnSpan() + 1, session );
-// }
-//
-// ResultSet rs = st.executeQuery();
-// try {
-// if ( !rs.next() ) {
-// if ( getFactory().getStatistics().isStatisticsEnabled() ) {
-// getFactory().getStatisticsImplementor()
-// .optimisticFailure( getEntityName() );
-// }
-// throw new StaleObjectStateException( getEntityName(), id );
-// }
-// }
-// finally {
-// rs.close();
-// }
-// }
-// finally {
-// session.getBatcher().closeStatement( st );
-// }
-//
-// }
-// catch ( SQLException sqle ) {
-// throw JDBCExceptionHelper.convert(
-// getFactory().getSQLExceptionConverter(),
-// sqle,
-// "could not lock: " +
-// MessageHelper.infoString( this, id, getFactory() ),
-// sql
-// );
-// }
-//
-// }
-//
-// }
-
public String[] toColumns(String alias, String propertyName) throws QueryException {
return propertyMapping.toColumns( alias, propertyName );
}
@@ -1872,6 +1786,9 @@
*/
protected String generateInsertString(boolean identityInsert, boolean[] includeProperty, int j) {
+ // todo : remove the identityInsert param and variations;
+ // identity-insert strings are now generated from generateIdentityInsertString()
+
Insert insert = new Insert( getFactory().getDialect() )
.setTableName( getTableName( j ) );
@@ -1911,6 +1828,39 @@
}
/**
+ * Used to generate an insery statement against the root table in the
+ * case of identifier generation strategies where the insert statement
+ * executions actually generates the identifier value.
+ *
+ * @param includeProperty indices of the properties to include in the
+ * insert statement.
+ * @return The insert SQL statement string
+ */
+ protected String generateIdentityInsertString(boolean[] includeProperty) {
+ Insert insert = identityDelegate.prepareIdentifierGeneratingInsert();
+ insert.setTableName( getTableName( 0 ) );
+
+ // add normal properties
+ for ( int i = 0; i < entityMetamodel.getPropertySpan(); i++ ) {
+ if ( includeProperty[i] && isPropertyOfTable( i, 0 ) ) {
+ // this property belongs on the table and is to be inserted
+ insert.addColumns( getPropertyColumnNames(i), propertyColumnInsertable[i] );
+ }
+ }
+
+ // add the discriminator
+ addDiscriminatorToInsert( insert );
+
+ // delegate already handles PK columns
+
+ if ( getFactory().getSettings().isCommentsEnabled() ) {
+ insert.setComment( "insert " + getEntityName() );
+ }
+
+ return insert.toStatementString();
+ }
+
+ /**
* Generate the SQL that deletes a row by id (and version)
*/
protected String generateDeleteString(int j) {
@@ -1933,24 +1883,23 @@
boolean[][] includeColumns,
int j,
PreparedStatement st,
- SessionImplementor session)
- throws HibernateException, SQLException {
+ SessionImplementor session) throws HibernateException, SQLException {
return dehydrate( id, fields, null, includeProperty, includeColumns, j, st, session, 1 );
}
/**
* Marshall the fields of a persistent instance to a prepared statement
*/
- protected int dehydrate(final Serializable id,
- final Object[] fields,
- final Object rowId,
- final boolean[] includeProperty,
- final boolean[][] includeColumns,
- final int j,
- final PreparedStatement ps,
- final SessionImplementor session,
- int index)
- throws SQLException, HibernateException {
+ protected int dehydrate(
+ final Serializable id,
+ final Object[] fields,
+ final Object rowId,
+ final boolean[] includeProperty,
+ final boolean[][] includeColumns,
+ final int j,
+ final PreparedStatement ps,
+ final SessionImplementor session,
+ int index) throws SQLException, HibernateException {
if ( log.isTraceEnabled() ) {
log.trace( "Dehydrating entity: " + MessageHelper.infoString( this, id, getFactory() ) );
@@ -1982,14 +1931,14 @@
* without resolving associations or collections. Question: should
* this really be here, or should it be sent back to Loader?
*/
- public Object[] hydrate(final ResultSet rs,
- final Serializable id,
- final Object object,
- final Loadable rootLoadable,
- final String[][] suffixedPropertyColumns,
- final boolean allProperties,
- final SessionImplementor session)
- throws SQLException, HibernateException {
+ public Object[] hydrate(
+ final ResultSet rs,
+ final Serializable id,
+ final Object object,
+ final Loadable rootLoadable,
+ final String[][] suffixedPropertyColumns,
+ final boolean allProperties,
+ final SessionImplementor session) throws SQLException, HibernateException {
if ( log.isTraceEnabled() ) {
log.trace( "Hydrating entity: " + MessageHelper.infoString( this, id, getFactory() ) );
@@ -2065,14 +2014,17 @@
}
/**
- * Perform an SQL INSERT, and then retrieve a generated identifier
+ * Perform an SQL INSERT, and then retrieve a generated identifier.
+ * <p/>
+ * This form is used for PostInsertIdentifierGenerator-style ids (IDENTITY,
+ * select, etc).
*/
- protected Serializable insert(final Object[] fields,
- final boolean[] notNull,
- String sql,
- final Object object,
- final SessionImplementor session)
- throws HibernateException {
+ protected Serializable insert(
+ final Object[] fields,
+ final boolean[] notNull,
+ String sql,
+ final Object object,
+ final SessionImplementor session) throws HibernateException {
if ( log.isTraceEnabled() ) {
log.trace( "Inserting entity: " + getEntityName() + " (native id)" );
@@ -2081,57 +2033,15 @@
}
}
- try {
-
- //do the insert
- PreparedStatement insert = session.getBatcher().prepareStatement( sql, useGetGeneratedKeys() );
- try {
- dehydrate( null, fields, notNull, propertyColumnInsertable, 0, insert, session );
-
- if ( useInsertSelectIdentity() ) {
- if ( !insert.execute() ) {
- while ( !insert.getMoreResults() && insert.getUpdateCount() != -1 ) {
- continue; // Do nothing (but stop checkstyle from complaining).
- }
- }
- //note early exit!
- ResultSet rs = insert.getResultSet();
- try {
- return IdentifierGeneratorFactory.getGeneratedIdentity( rs, getIdentifierType() );
- }
- finally {
- rs.close();
- }
- }
- else if ( useGetGeneratedKeys() ) {
- insert.executeUpdate();
- //note early exit!
- return IdentifierGeneratorFactory.getGeneratedIdentity(
- GetGeneratedKeysHelper.getGeneratedKey(insert),
- getIdentifierType()
- );
- }
- else {
- insert.executeUpdate();
- }
-
+ Binder binder = new Binder() {
+ public void bindValues(PreparedStatement ps) throws SQLException {
+ dehydrate( null, fields, notNull, propertyColumnInsertable, 0, ps, session );
}
- finally {
- session.getBatcher().closeStatement( insert );
+ public Object getEntity() {
+ return object;
}
-
- }
- catch ( SQLException sqle ) {
- throw JDBCExceptionHelper.convert(
- getFactory().getSQLExceptionConverter(),
- sqle,
- "could not insert: " + MessageHelper.infoString(this),
- sql
- );
- }
-
- return ( (PostInsertIdentifierGenerator) getIdentifierGenerator() ).getGenerated(session, object, this);
-
+ };
+ return identityDelegate.performInsert( sql, session, binder );
}
public String getIdentitySelectString() {
@@ -2152,16 +2062,19 @@
}
/**
- * Perform an SQL INSERT
+ * Perform an SQL INSERT.
+ * <p/>
+ * This for is used for all non-root tables as well as the root table
+ * in cases where the identifier value is known before the insert occurs.
*/
- protected void insert(final Serializable id,
- final Object[] fields,
- final boolean[] notNull,
- final int j,
- final String sql,
- final Object object,
- final SessionImplementor session)
- throws HibernateException {
+ protected void insert(
+ final Serializable id,
+ final Object[] fields,
+ final boolean[] notNull,
+ final int j,
+ final String sql,
+ final Object object,
+ final SessionImplementor session) throws HibernateException {
if ( isInverseTable( j ) ) {
return;
@@ -2237,17 +2150,17 @@
/**
* Perform an SQL UPDATE or SQL INSERT
*/
- protected void updateOrInsert(final Serializable id,
- final Object[] fields,
- final Object[] oldFields,
- final Object rowId,
- final boolean[] includeProperty,
- final int j,
- final Object oldVersion,
- final Object object,
- final String sql,
- final SessionImplementor session)
- throws HibernateException {
+ protected void updateOrInsert(
+ final Serializable id,
+ final Object[] fields,
+ final Object[] oldFields,
+ final Object rowId,
+ final boolean[] includeProperty,
+ final int j,
+ final Object oldVersion,
+ final Object object,
+ final String sql,
+ final SessionImplementor session) throws HibernateException {
if ( !isInverseTable( j ) ) {
@@ -2278,17 +2191,17 @@
}
- protected boolean update(final Serializable id,
- final Object[] fields,
- final Object[] oldFields,
- final Object rowId,
- final boolean[] includeProperty,
- final int j,
- final Object oldVersion,
- final Object object,
- final String sql,
- final SessionImplementor session)
- throws HibernateException {
+ protected boolean update(
+ final Serializable id,
+ final Object[] fields,
+ final Object[] oldFields,
+ final Object rowId,
+ final boolean[] includeProperty,
+ final int j,
+ final Object oldVersion,
+ final Object object,
+ final String sql,
+ final SessionImplementor session) throws HibernateException {
final boolean useVersion = j == 0 && isVersioned();
final boolean callable = isUpdateCallable( j );
@@ -2386,13 +2299,13 @@
/**
* Perform an SQL DELETE
*/
- protected void delete(final Serializable id,
- final Object version,
- final int j,
- final Object object,
- final String sql,
- final SessionImplementor session)
- throws HibernateException {
+ protected void delete(
+ final Serializable id,
+ final Object version,
+ final int j,
+ final Object object,
+ final String sql,
+ final SessionImplementor session) throws HibernateException {
if ( isInverseTable( j ) ) {
return;
@@ -2492,16 +2405,16 @@
/**
* Update an object
*/
- public void update(final Serializable id,
- final Object[] fields,
- final int[] dirtyFields,
- final boolean hasDirtyCollection,
- final Object[] oldFields,
- final Object oldVersion,
- final Object object,
- final Object rowId,
- final SessionImplementor session)
- throws HibernateException {
+ public void update(
+ final Serializable id,
+ final Object[] fields,
+ final int[] dirtyFields,
+ final boolean hasDirtyCollection,
+ final Object[] oldFields,
+ final Object oldVersion,
+ final Object object,
+ final Object rowId,
+ final SessionImplementor session) throws HibernateException {
//note: dirtyFields==null means we had no snapshot, and we couldn't get one using select-before-update
// oldFields==null just means we had no snapshot to begin with (we might have used select-before-update to get the dirtyFields)
@@ -2747,9 +2660,10 @@
StringHelper.qualify( alias, getSubclassTableKeyColumns( tableNumber ) ) ) + "=?";
}
- protected String renderSelect(final int[] tableNumbers,
- final int[] columnNumbers,
- final int[] formulaNumbers) {
+ protected String renderSelect(
+ final int[] tableNumbers,
+ final int[] columnNumbers,
+ final int[] formulaNumbers) {
Arrays.sort( tableNumbers ); //get 'em in the right order (not that it really matters)
@@ -2829,9 +2743,9 @@
sqlUpdateGeneratedValuesSelectString = generateUpdateGeneratedValuesSelectString();
}
if ( isIdentifierAssignedByInsert() ) {
- sqlIdentityInsertString = customSQLInsert[0] == null ?
- generateInsertString( true, getPropertyInsertability() ) :
- customSQLInsert[0];
+ identityDelegate = ( ( PostInsertIdentifierGenerator ) getIdentifierGenerator() )
+ .getInsertGeneratedIdentifierDelegate( this, getFactory().getDialect(), useGetGeneratedKeys() );
+ sqlIdentityInsertString = generateIdentityInsertString( getPropertyInsertability() );
}
else {
sqlIdentityInsertString = null;
Modified: trunk/Hibernate3/src/org/hibernate/sql/Insert.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/sql/Insert.java 2006-03-22 23:47:31 UTC (rev 9680)
+++ trunk/Hibernate3/src/org/hibernate/sql/Insert.java 2006-03-24 18:10:04 UTC (rev 9681)
@@ -14,22 +14,24 @@
* @author Gavin King
*/
public class Insert {
+ private Dialect dialect;
+ private String tableName;
+ private String comment;
+ private Map columns = new SequencedHashMap();
public Insert(Dialect dialect) {
this.dialect = dialect;
}
- private String comment;
+ protected Dialect getDialect() {
+ return dialect;
+ }
+
public Insert setComment(String comment) {
this.comment = comment;
return this;
}
- private Dialect dialect;
- private String tableName;
-
- private Map columns = new SequencedHashMap();
-
public Insert addColumn(String columnName) {
return addColumn(columnName, "?");
}
@@ -43,7 +45,9 @@
public Insert addColumns(String[] columnNames, boolean[] insertable) {
for ( int i=0; i<columnNames.length; i++ ) {
- if ( insertable[i] ) addColumn( columnNames[i] );
+ if ( insertable[i] ) {
+ addColumn( columnNames[i] );
+ }
}
return this;
}
@@ -59,7 +63,9 @@
public Insert addIdentityColumn(String columnName) {
String value = dialect.getIdentityInsertString();
- if (value!=null) addColumn(columnName, value);
+ if ( value != null ) {
+ addColumn( columnName, value );
+ }
return this;
}
@@ -70,7 +76,9 @@
public String toStatementString() {
StringBuffer buf = new StringBuffer( columns.size()*15 + tableName.length() + 10 );
- if (comment!=null) buf.append("/* ").append(comment).append(" */ ");
+ if ( comment != null ) {
+ buf.append( "/* " ).append( comment ).append( " */ " );
+ }
buf.append("insert into ")
.append(tableName);
if ( columns.size()==0 ) {
@@ -81,13 +89,17 @@
Iterator iter = columns.keySet().iterator();
while ( iter.hasNext() ) {
buf.append( iter.next() );
- if ( iter.hasNext() ) buf.append(", ");
+ if ( iter.hasNext() ) {
+ buf.append( ", " );
+ }
}
buf.append(") values (");
iter = columns.values().iterator();
while ( iter.hasNext() ) {
buf.append( iter.next() );
- if ( iter.hasNext() ) buf.append(", ");
+ if ( iter.hasNext() ) {
+ buf.append( ", " );
+ }
}
buf.append(')');
}
|
|
From: <hib...@li...> - 2006-03-22 23:48:11
|
Author: epbernard
Date: 2006-03-22 18:47:31 -0500 (Wed, 22 Mar 2006)
New Revision: 9680
Modified:
trunk/Hibernate3/src/org/hibernate/Query.java
trunk/Hibernate3/src/org/hibernate/transaction/CMTTransaction.java
Log:
better javadoc
open a bit the API for HEM
Modified: trunk/Hibernate3/src/org/hibernate/Query.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/Query.java 2006-03-22 23:21:44 UTC (rev 9679)
+++ trunk/Hibernate3/src/org/hibernate/Query.java 2006-03-22 23:47:31 UTC (rev 9680)
@@ -122,7 +122,7 @@
* the query, or null if the query returns no results.
*
* @return the single result or <tt>null</tt>
- * @throws HibernateException if there is more than one matching result
+ * @throws NonUniqueResultException if there is more than one matching result
*/
public Object uniqueResult() throws HibernateException;
@@ -154,8 +154,7 @@
* Entities retrieved by this query will be loaded in
* a read-only mode where Hibernate will never dirty-check
* them or make changes persistent.
- *
- * @see Session.setReadOnly(Object, boolean)
+ *
*/
public Query setReadOnly(boolean readOnly);
@@ -359,7 +358,7 @@
* Set a strategy for handling the query results. This can be used to change
* "shape" of the query result.
*
- * @param resultTransformer The transformer to apply
+ * @param transformer The transformer to apply
* @return this (for method chaining)
*/
public Query setResultTransformer(ResultTransformer transformer);
Modified: trunk/Hibernate3/src/org/hibernate/transaction/CMTTransaction.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/transaction/CMTTransaction.java 2006-03-22 23:21:44 UTC (rev 9679)
+++ trunk/Hibernate3/src/org/hibernate/transaction/CMTTransaction.java 2006-03-22 23:47:31 UTC (rev 9680)
@@ -22,8 +22,8 @@
private static final Log log = LogFactory.getLog(CMTTransaction.class);
- private final JDBCContext jdbcContext;
- private final TransactionFactory.Context transactionContext;
+ protected final JDBCContext jdbcContext;
+ protected final TransactionFactory.Context transactionContext;
private boolean begun;
@@ -87,7 +87,7 @@
}
- private javax.transaction.Transaction getTransaction() throws SystemException {
+ public javax.transaction.Transaction getTransaction() throws SystemException {
return transactionContext.getFactory().getTransactionManager().getTransaction();
}
|
|
From: <hib...@li...> - 2006-03-22 23:27:04
|
Author: epbernard
Date: 2006-03-22 18:21:44 -0500 (Wed, 22 Mar 2006)
New Revision: 9679
Added:
trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/transaction/JoinableCMTTransaction.java
trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/transaction/JoinableCMTTransactionFactory.java
trunk/HibernateExt/ejb/src/test/org/hibernate/ejb/test/ops/PersistTest.java
Removed:
trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/transaction/JoinableJTATransaction.java
trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/transaction/JoinableJTATransactionFactory.java
trunk/HibernateExt/ejb/src/test/org/hibernate/ejb/test/ops/CreateTest.java
Modified:
trunk/HibernateExt/ejb/lib/README.txt
trunk/HibernateExt/ejb/lib/ejb3-persistence.jar
trunk/HibernateExt/ejb/lib/hibernate-annotations.jar
trunk/HibernateExt/ejb/lib/javassist.jar
trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/AbstractEntityManagerImpl.java
trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/Ejb3Configuration.java
trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/EntityManagerImpl.java
trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/HibernateEntityManagerImplementor.java
trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/QueryImpl.java
trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/TransactionImpl.java
trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/packaging/PersistenceXmlLoader.java
trunk/HibernateExt/ejb/src/test/org/hibernate/ejb/test/EntityManagerTest.java
trunk/HibernateExt/ejb/src/test/org/hibernate/ejb/test/ejb3configuration/EntityManagerSerializationTest.java
Log:
EJB-117
EJB-137
EJB-134
EJB-37
Modified: trunk/HibernateExt/ejb/lib/README.txt
===================================================================
--- trunk/HibernateExt/ejb/lib/README.txt 2006-03-22 22:37:25 UTC (rev 9678)
+++ trunk/HibernateExt/ejb/lib/README.txt 2006-03-22 23:21:44 UTC (rev 9679)
@@ -3,5 +3,5 @@
ejb3-persistence (proposed final draft): required
hibernate-annotations (3.1beta9): required
-javassist (3.0): required
+javassist (3.1): required
jboss-archive-browsing (5.0.0alpha build: CVSTag=HEAD date=200507071617): required
Modified: trunk/HibernateExt/ejb/lib/ejb3-persistence.jar
===================================================================
(Binary files differ)
Modified: trunk/HibernateExt/ejb/lib/hibernate-annotations.jar
===================================================================
(Binary files differ)
Modified: trunk/HibernateExt/ejb/lib/javassist.jar
===================================================================
(Binary files differ)
Modified: trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/AbstractEntityManagerImpl.java
===================================================================
--- trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/AbstractEntityManagerImpl.java 2006-03-22 22:37:25 UTC (rev 9678)
+++ trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/AbstractEntityManagerImpl.java 2006-03-22 23:21:44 UTC (rev 9679)
@@ -8,12 +8,14 @@
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
+import javax.persistence.EntityExistsException;
import javax.persistence.EntityNotFoundException;
import javax.persistence.EntityTransaction;
import javax.persistence.FlushModeType;
import javax.persistence.LockModeType;
import javax.persistence.NoResultException;
import javax.persistence.NonUniqueResultException;
+import javax.persistence.OptimisticLockException;
import javax.persistence.PersistenceContextType;
import javax.persistence.PersistenceException;
import javax.persistence.Query;
@@ -28,6 +30,7 @@
import org.apache.commons.logging.LogFactory;
import org.hibernate.AssertionFailure;
import org.hibernate.FlushMode;
+import org.hibernate.HibernateException;
import org.hibernate.LockMode;
import org.hibernate.MappingException;
import org.hibernate.ObjectDeletedException;
@@ -35,12 +38,16 @@
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.StaleObjectStateException;
+import org.hibernate.StaleStateException;
+import org.hibernate.Transaction;
import org.hibernate.UnresolvableObjectException;
-import org.hibernate.Transaction;
-import org.hibernate.ejb.transaction.JoinableJTATransaction;
+import org.hibernate.ejb.transaction.JoinableCMTTransaction;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.engine.SessionImplementor;
+import org.hibernate.exception.ConstraintViolationException;
import org.hibernate.proxy.HibernateProxy;
+import org.hibernate.transaction.TransactionFactory;
+import org.hibernate.util.JTAHelper;
/**
* @author <a href="mailto:ga...@hi...">Gavin King</a>
@@ -67,57 +74,87 @@
public Query createQuery(String ejbqlString) {
//adjustFlushMode();
- return new QueryImpl( getSession().createQuery( ejbqlString ), this );
+ try {
+ return new QueryImpl( getSession().createQuery( ejbqlString ), this );
+ }
+ catch (HibernateException he) {
+ throwPersistenceException( he );
+ return null;
+ }
}
public Query createNamedQuery(String name) {
//adjustFlushMode();
- return new QueryImpl( getSession().getNamedQuery( name ), this );
+ try {
+ return new QueryImpl( getSession().getNamedQuery( name ), this );
+ }
+ catch (HibernateException he) {
+ throwPersistenceException( he );
+ return null;
+ }
}
public Query createNativeQuery(String sqlString) {
//adjustFlushMode();
- SQLQuery q = getSession().createSQLQuery( sqlString );
- return new QueryImpl( q, this );
+ try {
+ SQLQuery q = getSession().createSQLQuery( sqlString );
+ return new QueryImpl( q, this );
+ }
+ catch (HibernateException he) {
+ throwPersistenceException( he );
+ return null;
+ }
}
public Query createNativeQuery(String sqlString, Class resultClass) {
//adjustFlushMode();
- SQLQuery q = getSession().createSQLQuery( sqlString );
- q.addEntity( "alias1", resultClass.getName(), LockMode.READ );
- return new QueryImpl( q, this );
+ try {
+ SQLQuery q = getSession().createSQLQuery( sqlString );
+ q.addEntity( "alias1", resultClass.getName(), LockMode.READ );
+ return new QueryImpl( q, this );
+ }
+ catch (HibernateException he) {
+ throwPersistenceException( he );
+ return null;
+ }
}
public Query createNativeQuery(String sqlString, String resultSetMapping) {
//adjustFlushMode();
- SQLQuery q = getSession().createSQLQuery( sqlString );
- q.setResultSetMapping( resultSetMapping );
- return new QueryImpl( q, this );
+ try {
+ SQLQuery q = getSession().createSQLQuery( sqlString );
+ q.setResultSetMapping( resultSetMapping );
+ return new QueryImpl( q, this );
+ }
+ catch (HibernateException he) {
+ throwPersistenceException( he );
+ return null;
+ }
}
+ @SuppressWarnings("unchecked")
public <T> T getReference(Class<T> entityClass, Object primaryKey) {
//adjustFlushMode();
try {
- T rtn = (T) getSession().load( entityClass, (Serializable) primaryKey );
- return rtn;
+ return (T) getSession().load( entityClass, (Serializable) primaryKey );
}
- catch (ObjectNotFoundException e) {
- throwPersistenceException( new EntityNotFoundException( e.getMessage(), e ) );
- return null; //for the compiler to stop complaining
- }
catch (MappingException e) {
throw new IllegalArgumentException( e.getMessage(), e );
}
catch (ClassCastException e) {
throw new IllegalArgumentException( e.getMessage(), e );
}
+ catch (HibernateException he) {
+ throwPersistenceException( he );
+ return null;
+ }
}
+ @SuppressWarnings("unchecked")
public <A> A find(Class<A> entityClass, Object primaryKey) {
//adjustFlushMode();
try {
- A rtn = (A) getSession().get( entityClass, (Serializable) primaryKey );
- return rtn;
+ return (A) getSession().get( entityClass, (Serializable) primaryKey );
}
catch (ObjectNotFoundException e) {
//should not happen on the entity itself with get
@@ -129,6 +166,10 @@
catch (ClassCastException e) {
throw new IllegalArgumentException( e.getMessage(), e );
}
+ catch (HibernateException he) {
+ throwPersistenceException( he );
+ return null;
+ }
}
private void checkTransactionNeeded() {
@@ -149,8 +190,12 @@
catch (MappingException e) {
throw new IllegalArgumentException( e.getMessage() );
}
+ catch (HibernateException he) {
+ throwPersistenceException( he );
+ }
}
+ @SuppressWarnings("unchecked")
public <A> A merge(A entity) {
checkTransactionNeeded();
//adjustFlushMode();
@@ -166,6 +211,10 @@
catch (MappingException e) {
throw new IllegalArgumentException( e.getMessage(), e );
}
+ catch (HibernateException he) {
+ throwPersistenceException( he );
+ return null;
+ }
}
public void remove(Object entity) {
@@ -177,6 +226,9 @@
catch (MappingException e) {
throw new IllegalArgumentException( e.getMessage(), e );
}
+ catch (HibernateException he) {
+ throwPersistenceException( he );
+ }
}
public void refresh(Object entity) {
@@ -185,12 +237,12 @@
try {
getSession().refresh( entity );
}
- catch (UnresolvableObjectException uoe) {
- throwPersistenceException( new EntityNotFoundException( uoe ) );
- }
catch (MappingException e) {
throw new IllegalArgumentException( e.getMessage(), e );
}
+ catch (HibernateException he) {
+ throwPersistenceException( he );
+ }
}
public boolean contains(Object entity) {
@@ -205,12 +257,23 @@
catch (MappingException e) {
throw new IllegalArgumentException( e.getMessage(), e );
}
+ catch (HibernateException he) {
+ throwPersistenceException( he );
+ return false;
+ }
}
public void flush() {
- if ( ! isTransactionInProgress() ) throw new TransactionRequiredException( "no transaction is in progress" );
- //adjustFlushMode();
- getSession().flush();
+ try {
+ if ( ! isTransactionInProgress() ) {
+ throw new TransactionRequiredException( "no transaction is in progress" );
+ }
+ //adjustFlushMode();
+ getSession().flush();
+ }
+ catch (HibernateException he) {
+ throwPersistenceException( he );
+ }
}
public abstract Session getSession();
@@ -237,7 +300,12 @@
public void clear() {
//adjustFlushMode();
- getSession().clear();
+ try {
+ getSession().clear();
+ }
+ catch (HibernateException he) {
+ throwPersistenceException( he );
+ }
}
public FlushModeType getFlushMode() {
@@ -265,11 +333,17 @@
}
public void lock(Object entity, LockModeType lockMode) {
- if ( ! isTransactionInProgress() ) throw new TransactionRequiredException( "no transaction is in progress" );
- //adjustFlushMode();
- if ( !contains( entity ) ) throw new IllegalArgumentException( "entity not in the persistence context" );
- getSession().lock( entity, getLockMode( lockMode ) );
-
+ try {
+ if ( ! isTransactionInProgress() ) {
+ throw new TransactionRequiredException( "no transaction is in progress" );
+ }
+ //adjustFlushMode();
+ if ( !contains( entity ) ) throw new IllegalArgumentException( "entity not in the persistence context" );
+ getSession().lock( entity, getLockMode( lockMode ) );
+ }
+ catch (HibernateException he) {
+ throwPersistenceException( he );
+ }
}
private LockMode getLockMode(LockModeType lockMode) {
@@ -332,41 +406,93 @@
public void joinTransaction() {
//set the joined status
if ( transactionType == PersistenceUnitTransactionType.JTA ) {
- final Session session = getSession();
- final Transaction transaction = session.getTransaction();
- if ( transaction != null && transaction instanceof JoinableJTATransaction) {
- //can't handle it if not a joinnable transaction
- final JoinableJTATransaction joinableJTATransaction = (JoinableJTATransaction) session.getTransaction();
+ try {
+ final Session session = getSession();
+ final Transaction transaction = session.getTransaction();
+ if ( transaction != null && transaction instanceof JoinableCMTTransaction ) {
+ //can't handle it if not a joinnable transaction
+ final JoinableCMTTransaction joinableCMTTransaction = (JoinableCMTTransaction) session.getTransaction();
- if ( joinableJTATransaction.getStatus() == JoinableJTATransaction.JoinStatus.JOINED ) return; //no-op
- joinableJTATransaction.markForJoined();
- session.isOpen(); //register to the Tx
- if ( joinableJTATransaction.getStatus() == JoinableJTATransaction.JoinStatus.NOT_JOINED ) {
- throw new TransactionRequiredException( "No active JTA transaction on joinTransaction call" );
- }
- else if ( joinableJTATransaction.getStatus() == JoinableJTATransaction.JoinStatus.MARKED_FOR_JOINED ) {
- throw new AssertionFailure( "Transaction MARKED_FOR_JOINED after isOpen() call" );
- }
- //register clear on rollback
- joinableJTATransaction.registerSynchronization(
- new Synchronization() {
+ if ( joinableCMTTransaction.getStatus() == JoinableCMTTransaction.JoinStatus.JOINED ) {
+ return; //no-op
+ }
+ joinableCMTTransaction.markForJoined();
+ session.isOpen(); //register to the Tx
+ if ( joinableCMTTransaction.getStatus() == JoinableCMTTransaction.JoinStatus.NOT_JOINED ) {
+ throw new TransactionRequiredException( "No active JTA transaction on joinTransaction call" );
+ }
+ else
+ if ( joinableCMTTransaction.getStatus() == JoinableCMTTransaction.JoinStatus.MARKED_FOR_JOINED ) {
+ throw new AssertionFailure( "Transaction MARKED_FOR_JOINED after isOpen() call" );
+ }
+ //flush before completion and
+ //register clear on rollback
+ joinableCMTTransaction.registerSynchronization(
+ new Synchronization() {
+ public void beforeCompletion() {
+ boolean flush = false;
+ TransactionFactory.Context ctx = null;
+ try {
+ ctx = (TransactionFactory.Context) getSession();
+ JoinableCMTTransaction joinable = (JoinableCMTTransaction) session.getTransaction();
+ flush = !ctx.isFlushModeNever() &&
+ //ctx.isFlushBeforeCompletionEnabled() &&
+ //TODO probably make it ! isFlushBeforecompletion()
+ !JTAHelper.isRollback( joinable.getTransaction().getStatus() );
+ }
+ catch (SystemException se) {
+ log.error( "could not determine transaction status", se );
+ //throwPersistenceException will mark the transaction as rollbacked
+ throwPersistenceException(
+ new PersistenceException(
+ "could not determine transaction status in beforeCompletion()",
+ se
+ )
+ );
+ }
+ catch (HibernateException he) {
+ throwPersistenceException( he );
+ }
- public void beforeCompletion() {
- }
+ try {
+ if ( flush ) {
+ log.trace( "automatically flushing session" );
+ ctx.managedFlush();
+ }
+ }
+ catch (RuntimeException re) {
+ //throwPersistenceException will mark the transaction as rollbacked
+ if ( re instanceof HibernateException ) {
+ throwPersistenceException( (HibernateException) re );
+ }
+ else {
+ throwPersistenceException( new PersistenceException( re ) );
+ }
+ }
+ }
- public void afterCompletion(int status) {
- if ( Status.STATUS_ROLLEDBACK == status
- && transactionType == PersistenceUnitTransactionType.JTA ) {
- if ( session.isOpen() ) {
- session.clear();
+ public void afterCompletion(int status) {
+ try {
+ if ( Status.STATUS_ROLLEDBACK == status
+ && transactionType == PersistenceUnitTransactionType.JTA ) {
+ if ( session.isOpen() ) {
+ session.clear();
+ }
+ }
+ JoinableCMTTransaction joinable = (JoinableCMTTransaction) session.getTransaction();
+ joinable.resetStatus();
}
+ catch (HibernateException e) {
+ throwPersistenceException( e );
+ }
}
- JoinableJTATransaction joinable = (JoinableJTATransaction) session.getTransaction();
- joinable.resetStatus();
}
- }
- );
+ );
+ }
}
+ catch (HibernateException he) {
+ throwPersistenceException( he );
+ }
}
}
@@ -388,8 +514,30 @@
tx = new TransactionImpl( this );
}
- public PersistenceException throwPersistenceException(PersistenceException e) {
+ public void throwPersistenceException(PersistenceException e) {
if ( ! ( e instanceof NoResultException || ( e instanceof NonUniqueResultException ) ) ) markAsRollback();
throw e;
}
+
+ public void throwPersistenceException(HibernateException e) {
+ if ( e instanceof StaleStateException ) {
+ throwPersistenceException( new OptimisticLockException( e ) );
+ }
+ else if ( e instanceof ConstraintViolationException ) {
+ //FIXME this is bad cause ConstraintViolationException happens in other circumstances
+ throwPersistenceException( new EntityExistsException( e ) );
+ }
+ else if ( e instanceof ObjectNotFoundException ) {
+ throwPersistenceException( new EntityNotFoundException( e ) );
+ }
+ else if ( e instanceof org.hibernate.NonUniqueResultException ) {
+ throwPersistenceException( new NonUniqueResultException( e ) );
+ }
+ else if ( e instanceof UnresolvableObjectException ) {
+ throwPersistenceException( new EntityNotFoundException( e ) );
+ }
+ else {
+ throwPersistenceException( new PersistenceException( e ) );
+ }
+ }
}
Modified: trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/Ejb3Configuration.java
===================================================================
--- trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/Ejb3Configuration.java 2006-03-22 22:37:25 UTC (rev 9678)
+++ trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/Ejb3Configuration.java 2006-03-22 23:21:44 UTC (rev 9679)
@@ -47,7 +47,7 @@
import org.hibernate.ejb.packaging.JarVisitor;
import org.hibernate.ejb.packaging.PersistenceMetadata;
import org.hibernate.ejb.packaging.PersistenceXmlLoader;
-import org.hibernate.ejb.transaction.JoinableJTATransactionFactory;
+import org.hibernate.ejb.transaction.JoinableCMTTransactionFactory;
import org.hibernate.ejb.util.LogHelper;
import org.hibernate.engine.FilterDefinition;
import org.hibernate.event.EventListeners;
@@ -268,7 +268,7 @@
Properties properties = info.getProperties() != null ?
info.getProperties() :
new Properties();
- for ( Map.Entry entry : (Set<Map.Entry>) integration.keySet() ) {
+ for ( Map.Entry entry : (Set<Map.Entry>) integration.entrySet() ) {
if ( entry.getKey() instanceof String && entry.getValue() instanceof String ) {
properties.setProperty( (String) entry.getKey(), (String) entry.getValue() );
}
@@ -667,7 +667,7 @@
//settings that always apply to a compliant EJB3
preparedProperties.setProperty( Environment.AUTOCOMMIT, "true" );
preparedProperties.setProperty( Environment.USE_IDENTIFIER_ROLLBACK, "false" );
- preparedProperties.setProperty( Environment.FLUSH_BEFORE_COMPLETION, "true" );
+ preparedProperties.setProperty( Environment.FLUSH_BEFORE_COMPLETION, "false" );
preparedProperties.setProperty( HibernatePersistence.DISCARD_PC_ON_CLOSE, "false" );
//override the new defaults with the user defined ones
@@ -678,7 +678,7 @@
);
boolean hasTxStrategy = StringHelper.isNotEmpty( preparedProperties.getProperty( Environment.TRANSACTION_STRATEGY ) );
if (! hasTxStrategy && transactionType == PersistenceUnitTransactionType.JTA) {
- preparedProperties.setProperty( Environment.TRANSACTION_STRATEGY, JoinableJTATransactionFactory.class.getName() );
+ preparedProperties.setProperty( Environment.TRANSACTION_STRATEGY, JoinableCMTTransactionFactory.class.getName() );
}
else if (! hasTxStrategy && transactionType == PersistenceUnitTransactionType.RESOURCE_LOCAL) {
preparedProperties.setProperty( Environment.TRANSACTION_STRATEGY, JDBCTransactionFactory.class.getName() );
@@ -686,6 +686,13 @@
else {
new AssertionFailure("Unknown PersisntenceUnitTransactionType: " + transactionType);
}
+ if (hasTxStrategy) {
+ log.warn("Overriding " + Environment.TRANSACTION_STRATEGY + " is dangerous, this might break the EJB3 specification implementation");
+ }
+ if ( preparedProperties.getProperty( Environment.FLUSH_BEFORE_COMPLETION ).equals( "true" ) ) {
+ preparedProperties.setProperty( Environment.FLUSH_BEFORE_COMPLETION, "false" );
+ log.warn("Defining " + Environment.FLUSH_BEFORE_COMPLETION + "=true ignored in HEM");
+ }
return preparedProperties;
}
Modified: trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/EntityManagerImpl.java
===================================================================
--- trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/EntityManagerImpl.java 2006-03-22 22:37:25 UTC (rev 9678)
+++ trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/EntityManagerImpl.java 2006-03-22 23:21:44 UTC (rev 9679)
@@ -7,6 +7,7 @@
import org.hibernate.Session;
import org.hibernate.SessionFactory;
+import org.hibernate.HibernateException;
import org.hibernate.engine.SessionImplementor;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -79,8 +80,14 @@
public boolean isOpen() {
//adjustFlushMode(); //don't adjust, can't be done on closed EM
- if (open) getSession().isOpen(); //to force enlistment in tx
- return open;
+ try {
+ if (open) getSession().isOpen(); //to force enlistment in tx
+ return open;
+ }
+ catch (HibernateException he) {
+ throwPersistenceException(he);
+ return false;
+ }
}
}
Modified: trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/HibernateEntityManagerImplementor.java
===================================================================
--- trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/HibernateEntityManagerImplementor.java 2006-03-22 22:37:25 UTC (rev 9678)
+++ trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/HibernateEntityManagerImplementor.java 2006-03-22 23:21:44 UTC (rev 9679)
@@ -3,10 +3,13 @@
import javax.persistence.PersistenceException;
+import org.hibernate.HibernateException;
+
/**
* @author Emmanuel Bernard
*/
public interface HibernateEntityManagerImplementor extends HibernateEntityManager {
boolean isTransactionInProgress();
- public PersistenceException throwPersistenceException(PersistenceException e);
+ public void throwPersistenceException(PersistenceException e);
+ public void throwPersistenceException(HibernateException e);
}
Modified: trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/QueryImpl.java
===================================================================
--- trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/QueryImpl.java 2006-03-22 22:37:25 UTC (rev 9678)
+++ trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/QueryImpl.java 2006-03-22 23:21:44 UTC (rev 9679)
@@ -9,17 +9,17 @@
import javax.persistence.NoResultException;
import javax.persistence.Query;
import javax.persistence.TemporalType;
+import static javax.persistence.TemporalType.*;
import javax.persistence.TransactionRequiredException;
-import static javax.persistence.TemporalType.*;
import org.hibernate.CacheMode;
import org.hibernate.FlushMode;
-import org.hibernate.NonUniqueResultException;
+import org.hibernate.HibernateException;
import org.hibernate.SQLQuery;
/**
* @author <a href="mailto:ga...@hi...">Gavin King</a>
- * @version $Revision$
+ * @author Emmanuel Bernard
*/
public class QueryImpl implements Query, HibernateQuery {
private org.hibernate.Query query;
@@ -35,14 +35,27 @@
}
public int executeUpdate() {
- if ( ! em.isTransactionInProgress() ) {
- throw em.throwPersistenceException( new TransactionRequiredException("Executing an update/delete query") );
+ try {
+ if ( ! em.isTransactionInProgress() ) {
+ em.throwPersistenceException( new TransactionRequiredException("Executing an update/delete query") );
+ return 0;
+ }
+ return query.executeUpdate();
}
- return query.executeUpdate();
+ catch (HibernateException he) {
+ em.throwPersistenceException(he);
+ return 0;
+ }
}
public List getResultList() {
- return query.list();
+ try {
+ return query.list();
+ }
+ catch (HibernateException he) {
+ em.throwPersistenceException(he);
+ return null;
+ }
}
public Object getSingleResult() {
@@ -55,9 +68,9 @@
return result;
}
- catch (NonUniqueResultException e) {
- em.throwPersistenceException( new javax.persistence.NonUniqueResultException( e.getMessage() ) );
- return null; //for the compiler to stop complaining
+ catch (HibernateException he) {
+ em.throwPersistenceException(he);
+ return null;
}
}
@@ -123,49 +136,73 @@
}
public Query setParameter(String name, Object value) {
- if ( value instanceof Collection ) {
- query.setParameterList( name, (Collection) value );
+ try {
+ if ( value instanceof Collection ) {
+ query.setParameterList( name, (Collection) value );
+ }
+ else {
+ query.setParameter( name, value );
+ }
+ return this;
}
- else {
- query.setParameter( name, value );
+ catch (HibernateException he) {
+ em.throwPersistenceException(he);
+ return null;
}
- return this;
}
public Query setParameter(String name, Date value, TemporalType temporalType) {
- if ( temporalType == DATE ) {
- query.setDate( name, value );
+ try {
+ if ( temporalType == DATE ) {
+ query.setDate( name, value );
+ }
+ else if ( temporalType == TIME ) {
+ query.setTime( name, value );
+ }
+ else if ( temporalType == TIMESTAMP ) {
+ query.setTimestamp( name, value );
+ }
+ return this;
}
- else if ( temporalType == TIME ) {
- query.setTime( name, value );
+ catch (HibernateException he) {
+ em.throwPersistenceException(he);
+ return null;
}
- else if ( temporalType == TIMESTAMP ) {
- query.setTimestamp( name, value );
- }
- return this;
}
public Query setParameter(String name, Calendar value, TemporalType temporalType) {
- if ( temporalType == DATE ) {
- query.setCalendarDate( name, value );
+ try {
+ if ( temporalType == DATE ) {
+ query.setCalendarDate( name, value );
+ }
+ else if ( temporalType == TIME ) {
+ throw new IllegalArgumentException( "not yet implemented" );
+ }
+ else if ( temporalType == TIMESTAMP ) {
+ query.setCalendar( name, value );
+ }
+ return this;
}
- else if ( temporalType == TIME ) {
- throw new IllegalArgumentException( "not yet implemented" );
+ catch (HibernateException he) {
+ em.throwPersistenceException(he);
+ return null;
}
- else if ( temporalType == TIMESTAMP ) {
- query.setCalendar( name, value );
- }
- return this;
}
public Query setParameter(int position, Object value) {
- if ( isEJBQLQuery() ) {
- this.setParameter( Integer.toString(position), value );
+ try {
+ if ( isEJBQLQuery() ) {
+ this.setParameter( Integer.toString(position), value );
+ }
+ else {
+ query.setParameter( position - 1, value );
+ }
+ return this;
}
- else {
- query.setParameter( position - 1, value );
+ catch (HibernateException he) {
+ em.throwPersistenceException(he);
+ return null;
}
- return this;
}
private boolean isEJBQLQuery() {
@@ -173,41 +210,53 @@
}
public Query setParameter(int position, Date value, TemporalType temporalType) {
- if ( isEJBQLQuery() ) {
- String name = Integer.toString(position);
- this.setParameter( name, value, temporalType );
- }
- else {
- if ( temporalType == DATE ) {
- query.setDate( position - 1, value );
+ try {
+ if ( isEJBQLQuery() ) {
+ String name = Integer.toString(position);
+ this.setParameter( name, value, temporalType );
}
- else if ( temporalType == TIME ) {
- query.setTime( position - 1, value );
+ else {
+ if ( temporalType == DATE ) {
+ query.setDate( position - 1, value );
+ }
+ else if ( temporalType == TIME ) {
+ query.setTime( position - 1, value );
+ }
+ else if ( temporalType == TIMESTAMP ) {
+ query.setTimestamp( position - 1, value );
+ }
}
- else if ( temporalType == TIMESTAMP ) {
- query.setTimestamp( position - 1, value );
- }
+ return this;
}
- return this;
+ catch (HibernateException he) {
+ em.throwPersistenceException(he);
+ return null;
+ }
}
public Query setParameter(int position, Calendar value, TemporalType temporalType) {
- if ( isEJBQLQuery() ) {
- String name = Integer.toString(position);
- this.setParameter( name, value, temporalType);
- }
- else {
- if ( temporalType == DATE ) {
- query.setCalendarDate( position - 1, value );
+ try {
+ if ( isEJBQLQuery() ) {
+ String name = Integer.toString(position);
+ this.setParameter( name, value, temporalType);
}
- else if ( temporalType == TIME ) {
- throw new IllegalArgumentException( "not yet implemented" );
+ else {
+ if ( temporalType == DATE ) {
+ query.setCalendarDate( position - 1, value );
+ }
+ else if ( temporalType == TIME ) {
+ throw new IllegalArgumentException( "not yet implemented" );
+ }
+ else if ( temporalType == TIMESTAMP ) {
+ query.setCalendar( position - 1, value );
+ }
}
- else if ( temporalType == TIMESTAMP ) {
- query.setCalendar( position - 1, value );
- }
+ return this;
}
- return this;
+ catch (HibernateException he) {
+ em.throwPersistenceException(he);
+ return null;
+ }
}
public Query setFlushMode(FlushModeType flushMode) {
Modified: trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/TransactionImpl.java
===================================================================
--- trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/TransactionImpl.java 2006-03-22 22:37:25 UTC (rev 9678)
+++ trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/TransactionImpl.java 2006-03-22 23:21:44 UTC (rev 9679)
@@ -7,6 +7,7 @@
import org.hibernate.Session;
import org.hibernate.Transaction;
+import org.hibernate.HibernateException;
/**
* @author Gavin King
@@ -27,12 +28,17 @@
}
public void begin() {
- rollbackOnly = false;
- if ( tx != null && tx.isActive() ) {
- throw new IllegalStateException( "Transaction already active" );
+ try {
+ rollbackOnly = false;
+ if ( tx != null && tx.isActive() ) {
+ throw new IllegalStateException( "Transaction already active" );
+ }
+ //entityManager.adjustFlushMode();
+ tx = getSession().beginTransaction();
}
- //entityManager.adjustFlushMode();
- tx = getSession().beginTransaction();
+ catch (HibernateException he) {
+ entityManager.throwPersistenceException(he);
+ }
}
public void commit() {
@@ -70,7 +76,7 @@
try {
tx.rollback();
}
- catch (RuntimeException e) {
+ catch (Exception e) {
throw new PersistenceException("unexpected error when rollbacking", e);
}
finally {
Modified: trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/packaging/PersistenceXmlLoader.java
===================================================================
--- trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/packaging/PersistenceXmlLoader.java 2006-03-22 22:37:25 UTC (rev 9678)
+++ trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/packaging/PersistenceXmlLoader.java 2006-03-22 23:21:44 UTC (rev 9679)
@@ -15,9 +15,9 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.hibernate.cfg.EJB3DTDEntityResolver;
import org.hibernate.ejb.HibernatePersistence;
import org.hibernate.util.StringHelper;
-import org.hibernate.cfg.EJB3DTDEntityResolver;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
@@ -51,8 +51,8 @@
docBuilderFactory.setNamespaceAware( true );
try {
//otherwise Xerces fails in validation
- docBuilderFactory.setAttribute( "http://apache.org/xml/features/validation/schema", true);
- }
+ docBuilderFactory.setAttribute( "http://apache.org/xml/features/validation/schema", true );
+ }
catch (IllegalArgumentException e) {
docBuilderFactory.setValidating( false );
docBuilderFactory.setNamespaceAware( false );
@@ -60,9 +60,9 @@
InputSource source = new InputSource( is );
DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
docBuilder.setEntityResolver( resolver );
- docBuilder.setErrorHandler( new ErrorLogger("XML InputStream", errors, resolver) );
+ docBuilder.setErrorHandler( new ErrorLogger( "XML InputStream", errors, resolver ) );
Document doc = docBuilder.parse( source );
- if ( errors.size() != 0 ) {
+ if ( errors.size() != 0 ) {
throw new PersistenceException( "invalid persistence.xml", (Throwable) errors.get( 0 ) );
}
return doc;
@@ -82,19 +82,19 @@
PersistenceMetadata metadata = parsePersistenceUnit( element );
//override properties of metadata if needed
String provider = (String) overrides.get( HibernatePersistence.PROVIDER );
- if (provider != null) {
+ if ( provider != null ) {
metadata.setProvider( provider );
}
String transactionType = (String) overrides.get( HibernatePersistence.TRANSACTION_TYPE );
- if (transactionType != null) {
+ if ( transactionType != null ) {
metadata.setTransactionType( PersistenceXmlLoader.getTransactionType( transactionType ) );
}
String dataSource = (String) overrides.get( HibernatePersistence.JTA_DATASOURCE );
- if (dataSource != null) {
+ if ( dataSource != null ) {
metadata.setJtaDatasource( dataSource );
}
dataSource = (String) overrides.get( HibernatePersistence.NON_JTA_DATASOURCE );
- if (dataSource != null) {
+ if ( dataSource != null ) {
metadata.setNonJtaDatasource( dataSource );
}
Properties properties = metadata.getProps();
@@ -176,33 +176,44 @@
}
public static PersistenceUnitTransactionType getTransactionType(String elementContent) {
- if (StringHelper.isEmpty( elementContent ) ) return PersistenceUnitTransactionType.JTA;
- else if ( elementContent.equalsIgnoreCase( "JTA" ) ) return PersistenceUnitTransactionType.JTA;
- else if ( elementContent.equalsIgnoreCase( "RESOURCE_LOCAL" ) ) return PersistenceUnitTransactionType.RESOURCE_LOCAL;
- else throw new PersistenceException("Unknown TransactionType: " + elementContent);
+ if ( StringHelper.isEmpty( elementContent ) ) {
+ return PersistenceUnitTransactionType.JTA;
+ }
+ else if ( elementContent.equalsIgnoreCase( "JTA" ) ) {
+ return PersistenceUnitTransactionType.JTA;
+ }
+ else if ( elementContent.equalsIgnoreCase( "RESOURCE_LOCAL" ) ) {
+ return PersistenceUnitTransactionType.RESOURCE_LOCAL;
+ }
+ else {
+ throw new PersistenceException( "Unknown TransactionType: " + elementContent );
+ }
}
public static class ErrorLogger implements ErrorHandler {
private String file;
private List errors;
- private EntityResolver resolver;
- ErrorLogger(String file, List errors, EntityResolver resolver) {
- this.file=file;
+ private EntityResolver resolver;
+
+ ErrorLogger(String file, List errors, EntityResolver resolver) {
+ this.file = file;
this.errors = errors;
- this.resolver = resolver;
- }
+ this.resolver = resolver;
+ }
+
public void error(SAXParseException error) {
- if (resolver instanceof EJB3DTDEntityResolver)
- {
- if (((EJB3DTDEntityResolver)resolver).isResolved() == false) return;
- }
- log.error( "Error parsing XML: " + file + '(' + error.getLineNumber() + ") " + error.getMessage() );
- errors.add(error);
+ if ( resolver instanceof EJB3DTDEntityResolver ) {
+ if ( ( (EJB3DTDEntityResolver) resolver ).isResolved() == false ) return;
+ }
+ log.error( "Error parsing XML: " + file + '(' + error.getLineNumber() + ") " + error.getMessage() );
+ errors.add( error );
}
+
public void fatalError(SAXParseException error) {
- log.error( "Error parsing XML: " + file + '(' + error.getLineNumber() + ") " + error.getMessage() );
- errors.add(error);
+ log.error( "Error parsing XML: " + file + '(' + error.getLineNumber() + ") " + error.getMessage() );
+ errors.add( error );
}
+
public void warning(SAXParseException warn) {
log.warn( "Warning parsing XML: " + file + '(' + warn.getLineNumber() + ") " + warn.getMessage() );
}
Copied: trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/transaction/JoinableCMTTransaction.java (from rev 9647, trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/transaction/JoinableJTATransaction.java)
===================================================================
--- trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/transaction/JoinableJTATransaction.java 2006-03-17 11:09:10 UTC (rev 9647)
+++ trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/transaction/JoinableCMTTransaction.java 2006-03-22 23:21:44 UTC (rev 9679)
@@ -0,0 +1,84 @@
+//$Id: $
+package org.hibernate.ejb.transaction;
+
+import javax.transaction.SystemException;
+
+import org.hibernate.HibernateException;
+import org.hibernate.TransactionException;
+import org.hibernate.jdbc.JDBCContext;
+import org.hibernate.transaction.CMTTransaction;
+import org.hibernate.transaction.TransactionFactory;
+import org.hibernate.util.JTAHelper;
+
+/**
+ * Implements a joinable transaction. Until the transaction is marked for joined, the TM.isTransactionInProgress()
+ * must return false
+ *
+ * @author Emmanuel Bernard
+ */
+public class JoinableCMTTransaction extends CMTTransaction {
+ private JoinStatus status;
+ public JoinableCMTTransaction( JDBCContext jdbcContext, TransactionFactory.Context transactionContext ) {
+ super( jdbcContext, transactionContext );
+ status = JoinStatus.MARKED_FOR_JOINED;
+ tryJoiningTransaction();
+ }
+
+ public boolean isTransactionInProgress(
+ JDBCContext jdbcContext,
+ TransactionFactory.Context transactionContext) {
+ try {
+ return JTAHelper.isTransactionInProgress(
+ transactionContext.getFactory().getTransactionManager().getTransaction()
+ );
+ }
+ catch( SystemException se ) {
+ throw new TransactionException( "Unable to check transaction status", se );
+ }
+ }
+
+ void tryJoiningTransaction() {
+ if (status == JoinStatus.MARKED_FOR_JOINED) {
+ if ( isTransactionInProgress(jdbcContext, transactionContext) ) {
+ status = JoinStatus.JOINED;
+ }
+ else {
+ status = JoinStatus.NOT_JOINED;
+ }
+ }
+ }
+
+ @Override
+ public void begin() throws HibernateException {
+ super.begin();
+ status = JoinStatus.JOINED;
+ }
+
+ @Override
+ public void commit() throws HibernateException {
+ /* this method is not supposed to be called
+ * it breaks the flushBeforeCompletion flag optimizeation
+ * regarding flushing skip.
+ * In its current form, it will generate too much flush() calls
+ */
+ super.commit();
+ }
+
+
+
+ public JoinStatus getStatus() {
+ return status;
+ }
+
+ public void resetStatus() { status = JoinStatus.NOT_JOINED; }
+
+ public void markForJoined() {
+ if (status != JoinStatus.JOINED) status = JoinStatus.MARKED_FOR_JOINED;
+ }
+
+ public static enum JoinStatus {
+ NOT_JOINED,
+ MARKED_FOR_JOINED,
+ JOINED
+ }
+}
Copied: trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/transaction/JoinableCMTTransactionFactory.java (from rev 9647, trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/transaction/JoinableJTATransactionFactory.java)
===================================================================
--- trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/transaction/JoinableJTATransactionFactory.java 2006-03-17 11:09:10 UTC (rev 9647)
+++ trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/transaction/JoinableCMTTransactionFactory.java 2006-03-22 23:21:44 UTC (rev 9679)
@@ -0,0 +1,30 @@
+//$Id: $
+package org.hibernate.ejb.transaction;
+
+import org.hibernate.HibernateException;
+import org.hibernate.Transaction;
+import org.hibernate.jdbc.JDBCContext;
+import org.hibernate.transaction.CMTTransactionFactory;
+
+/**
+ * A transaction is in progress if the underlying JTA tx is in progress and if the Tx is marked as
+ * MARKED_FOR_JOINED
+ *
+ * @author Emmanuel Bernard
+ */
+public class JoinableCMTTransactionFactory extends CMTTransactionFactory {
+ public Transaction createTransaction(JDBCContext jdbcContext, Context transactionContext)
+ throws HibernateException {
+ return new JoinableCMTTransaction( jdbcContext, transactionContext );
+ }
+
+ @Override
+ public boolean isTransactionInProgress(
+ JDBCContext jdbcContext, Context transactionContext, Transaction transaction
+ ) {
+ if ( transaction == null ) return false; //should not happen though
+ JoinableCMTTransaction joinableCMTTransaction = ( (JoinableCMTTransaction) transaction );
+ joinableCMTTransaction.tryJoiningTransaction();
+ return joinableCMTTransaction.isTransactionInProgress(jdbcContext, transactionContext);
+ }
+}
Deleted: trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/transaction/JoinableJTATransaction.java
===================================================================
--- trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/transaction/JoinableJTATransaction.java 2006-03-22 22:37:25 UTC (rev 9678)
+++ trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/transaction/JoinableJTATransaction.java 2006-03-22 23:21:44 UTC (rev 9679)
@@ -1,89 +0,0 @@
-//$Id: $
-package org.hibernate.ejb.transaction;
-
-import javax.naming.InitialContext;
-import javax.transaction.SystemException;
-import javax.transaction.UserTransaction;
-
-import org.hibernate.HibernateException;
-import org.hibernate.TransactionException;
-import org.hibernate.jdbc.JDBCContext;
-import org.hibernate.transaction.JTATransaction;
-import org.hibernate.transaction.TransactionFactory;
-import org.hibernate.util.JTAHelper;
-
-/**
- * Implements a joinable transaction. Until the transaction is marked for joined, the TM.isTransactionInProgress()
- * must return false
- * If a
- * @author Emmanuel Bernard
- */
-public class JoinableJTATransaction extends JTATransaction {
- private JoinStatus status;
- public JoinableJTATransaction(
- InitialContext context, String utName, JDBCContext jdbcContext,
- TransactionFactory.Context transactionContext
- ) {
- super( context, utName, jdbcContext, transactionContext );
- status = JoinStatus.MARKED_FOR_JOINED;
- tryJoiningTransaction();
- }
-
- void tryJoiningTransaction() {
- if (status == JoinStatus.MARKED_FOR_JOINED) {
- try {
- UserTransaction ut = getUserTransaction();
- if ( ut != null && JTAHelper.isInProgress( ut.getStatus() ) ) {
- status = JoinStatus.JOINED;
- }
- else {
- status = JoinStatus.NOT_JOINED;
- }
- }
- catch( SystemException se ) {
- throw new TransactionException( "Unable to check transaction status", se );
- }
- }
- }
-
- @Override
- public void begin() throws HibernateException {
- super.begin();
- status = JoinStatus.JOINED;
- }
-
- public JoinStatus getStatus() {
- return status;
- }
-
- public void resetStatus() { status = JoinStatus.NOT_JOINED; }
-
- public void markForJoined() {
- if (status != JoinStatus.JOINED) status = JoinStatus.MARKED_FOR_JOINED;
- }
-
- public boolean isTransactionInProgress() {
- if (status != JoinableJTATransaction.JoinStatus.JOINED) {
- return false;
- }
- try {
- UserTransaction ut = getUserTransaction();
- if ( ut != null && JTAHelper.isInProgress( ut.getStatus() ) ) {
- return true;
- }
- else {
- resetStatus();
- return false;
- }
- }
- catch( SystemException se ) {
- throw new TransactionException( "Unable to check transaction status", se );
- }
- }
-
- public static enum JoinStatus {
- NOT_JOINED,
- MARKED_FOR_JOINED,
- JOINED
- }
-}
Deleted: trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/transaction/JoinableJTATransactionFactory.java
===================================================================
--- trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/transaction/JoinableJTATransactionFactory.java 2006-03-22 22:37:25 UTC (rev 9678)
+++ trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/transaction/JoinableJTATransactionFactory.java 2006-03-22 23:21:44 UTC (rev 9679)
@@ -1,31 +0,0 @@
-//$Id: $
-package org.hibernate.ejb.transaction;
-
-import org.hibernate.HibernateException;
-import org.hibernate.Transaction;
-import org.hibernate.jdbc.JDBCContext;
-import org.hibernate.transaction.JTATransactionFactory;
-
-/**
- * A transaction is in progress if the underlying JTA tx is in progress and if the Tx is marked as
- * MARKED_FOR_JOINED
- *
- * @author Emmanuel Bernard
- */
-public class JoinableJTATransactionFactory extends JTATransactionFactory {
- public Transaction createTransaction(JDBCContext jdbcContext, Context transactionContext)
- throws HibernateException {
- return new JoinableJTATransaction( context, utName, jdbcContext, transactionContext );
- }
-
- @Override
- public boolean isTransactionInProgress(
- JDBCContext jdbcContext, Context transactionContext, Transaction transaction
- ) {
- if ( !super.isTransactionInProgress( jdbcContext, transactionContext, transaction ) ) return false;
- if ( transaction == null ) return false; //should not happen though
- JoinableJTATransaction joinableJTATransaction = ( (JoinableJTATransaction) transaction );
- joinableJTATransaction.tryJoiningTransaction();
- return joinableJTATransaction.isTransactionInProgress();
- }
-}
Modified: trunk/HibernateExt/ejb/src/test/org/hibernate/ejb/test/EntityManagerTest.java
===================================================================
--- trunk/HibernateExt/ejb/src/test/org/hibernate/ejb/test/EntityManagerTest.java 2006-03-22 22:37:25 UTC (rev 9678)
+++ trunk/HibernateExt/ejb/src/test/org/hibernate/ejb/test/EntityManagerTest.java 2006-03-22 23:21:44 UTC (rev 9679)
@@ -11,11 +11,11 @@
import java.util.Map;
import javax.persistence.EntityManager;
import javax.persistence.FlushModeType;
+import javax.persistence.PersistenceException;
import javax.persistence.Query;
import org.hibernate.FlushMode;
import org.hibernate.HibernateException;
-import org.hibernate.QueryException;
import org.hibernate.ejb.HibernateEntityManager;
import org.hibernate.ejb.HibernateEntityManagerFactory;
import org.hibernate.stat.Statistics;
@@ -263,7 +263,7 @@
Query query = em.createQuery("SELECT p FETCH JOIN p.distributors FROM Item p");
query.getSingleResult();
}
- catch (QueryException e) {
+ catch (PersistenceException e) {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
ObjectOutput out = new ObjectOutputStream( stream );
out.writeObject( e );
@@ -272,13 +272,13 @@
stream.close();
ByteArrayInputStream byteIn = new ByteArrayInputStream( serialized );
ObjectInputStream in = new ObjectInputStream(byteIn);
- QueryException deserializedException = (QueryException) in.readObject();
+ PersistenceException deserializedException = (PersistenceException) in.readObject();
in.close();
byteIn.close();
- assertNull( deserializedException.getCause() );
- assertNull( e.getCause() );
+ assertNull( deserializedException.getCause().getCause() );
+ assertNull( e.getCause().getCause() );
}
- em.getTransaction().commit();
+ em.getTransaction().rollback();
em.close();
Modified: trunk/HibernateExt/ejb/src/test/org/hibernate/ejb/test/ejb3configuration/EntityManagerSerializationTest.java
===================================================================
--- trunk/HibernateExt/ejb/src/test/org/hibernate/ejb/test/ejb3configuration/EntityManagerSerializationTest.java 2006-03-22 22:37:25 UTC (rev 9678)
+++ trunk/HibernateExt/ejb/src/test/org/hibernate/ejb/test/ejb3configuration/EntityManagerSerializationTest.java 2006-03-22 23:21:44 UTC (rev 9679)
@@ -68,7 +68,7 @@
em.getTransaction().begin();
item = em.find( Item.class, item.getName() );
item.setDescr( item.getDescr() + "-Amsterdam");
- cat = em.find(Cat.class, cat.getId() );
+ cat = (Cat) em.createQuery( "from " + Cat.class.getName() ).getSingleResult();
cat.setLength( 34 );
em.flush();
em.remove( item );
Deleted: trunk/HibernateExt/ejb/src/test/org/hibernate/ejb/test/ops/CreateTest.java
===================================================================
--- trunk/HibernateExt/ejb/src/test/org/hibernate/ejb/test/ops/CreateTest.java 2006-03-22 22:37:25 UTC (rev 9678)
+++ trunk/HibernateExt/ejb/src/test/org/hibernate/ejb/test/ops/CreateTest.java 2006-03-22 23:21:44 UTC (rev 9679)
@@ -1,223 +0,0 @@
-//$Id$
-package org.hibernate.ejb.test.ops;
-
-import java.util.ArrayList;
-import java.util.Collection;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-import org.hibernate.PersistentObjectException;
-import org.hibernate.Session;
-import org.hibernate.Transaction;
-import org.hibernate.cfg.Configuration;
-import org.hibernate.cfg.Environment;
-import org.hibernate.ejb.test.EJB3TestCase;
-import org.hibernate.exception.ConstraintViolationException;
-
-/**
- * @author Gavin King
- */
-public class CreateTest extends EJB3TestCase {
-
- public CreateTest(String str) {
- super( str );
- }
-
- public void testCreateTree() {
-
- clearCounts();
-
- Session s = openSession();
- Transaction tx = s.beginTransaction();
- Node root = new Node( "root" );
- Node child = new Node( "child" );
- root.addChild( child );
- s.persist( root );
- tx.commit();
- s.close();
-
- assertInsertCount( 2 );
- assertUpdateCount( 0 );
-
- s = openSession();
- tx = s.beginTransaction();
- root = (Node) s.get( Node.class, "root" );
- Node child2 = new Node( "child2" );
- root.addChild( child2 );
- tx.commit();
- s.close();
-
- assertInsertCount( 3 );
- assertUpdateCount( 0 );
- }
-
- public void testCreateTreeWithGeneratedId() {
-
- clearCounts();
-
- Session s = openSession();
- Transaction tx = s.beginTransaction();
- NumberedNode root = new NumberedNode( "root" );
- NumberedNode child = new NumberedNode( "child" );
- root.addChild( child );
- s.persist( root );
- tx.commit();
- s.close();
-
- assertInsertCount( 2 );
- assertUpdateCount( 0 );
-
- s = openSession();
- tx = s.beginTransaction();
- root = (NumberedNode) s.get( NumberedNode.class, new Long( root.getId() ) );
- NumberedNode child2 = new NumberedNode( "child2" );
- root.addChild( child2 );
- tx.commit();
- s.close();
-
- assertInsertCount( 3 );
- assertUpdateCount( 0 );
- }
-
- public void testCreateException() {
- Session s = openSession();
- Transaction tx = s.beginTransaction();
- Node dupe = new Node( "dupe" );
- s.persist( dupe );
- s.persist( dupe );
- tx.commit();
- s.close();
-
- s = openSession();
- tx = s.beginTransaction();
- s.persist( dupe );
- try {
- tx.commit();
- assertFalse( true );
- }
- catch (ConstraintViolationException cve) {
- //verify that an exception is thrown!
- }
- tx.rollback();
- s.close();
-
- Node nondupe = new Node( "nondupe" );
- nondupe.addChild( dupe );
-
- s = openSession();
- tx = s.beginTransaction();
- s.persist( nondupe );
- try {
- tx.commit();
- assertFalse( true );
- }
- catch (ConstraintViolationException cve) {
- //verify that an exception is thrown!
- }
- tx.rollback();
- s.close();
- }
-
- public void testCreateExceptionWithGeneratedId() {
- Session s = openSession();
- Transaction tx = s.beginTransaction();
- NumberedNode dupe = new NumberedNode( "dupe" );
- s.persist( dupe );
- s.persist( dupe );
- tx.commit();
- s.close();
-
- s = openSession();
- tx = s.beginTransaction();
- try {
- s.persist( dupe );
- assertFalse( true );
- }
- catch (PersistentObjectException poe) {
- //verify that an exception is thrown!
- }
- tx.rollback();
- s.close();
-
- NumberedNode nondupe = new NumberedNode( "nondupe" );
- nondupe.addChild( dupe );
-
- s = openSession();
- tx = s.beginTransaction();
- try {
- s.persist( nondupe );
- assertFalse( true );
- }
- catch (PersistentObjectException poe) {
- //verify that an exception is thrown!
- }
- tx.rollback();
- s.close();
- }
-
- public void testBasic() throws Exception {
- Session s;
- Transaction tx;
- s = openSession();
- tx = s.beginTransaction();
- Employer er = new Employer();
- Employee ee = new Employee();
- s.persist( ee );
- Collection erColl = new ArrayList();
- Collection eeColl = new ArrayList();
- erColl.add( ee );
- eeColl.add( er );
- er.setEmployees( erColl );
- ee.setEmployers( eeColl );
- tx.commit();
- s.close();
-
- s = openSession();
- tx = s.beginTransaction();
- er = (Employer) s.load( Employer.class, er.getId() );
- assertNotNull( er );
- assertNotNull( er.getEmployees() );
- assertEquals( 1, er.getEmployees().size() );
- Employee eeFromDb = (Employee) er.getEmployees().iterator().next();
- assertEquals( ee.getId(), eeFromDb.getId() );
- tx.commit();
- s.close();
- }
-
- private void clearCounts() {
- getSessions().getStatistics().clear();
- }
-
- private void assertInsertCount(int count) {
- int inserts = (int) getSessions().getStatistics().getEntityInsertCount();
- assertEquals( count, inserts );
- }
-
- private void assertUpdateCount(int count) {
- int updates = (int) getSessions().getStatistics().getEntityUpdateCount();
- assertEquals( count, updates );
- }
-
- protected void configure(Configuration cfg) {
- super.configure( cfg );
- cfg.setProperty( Environment.GENERATE_STATISTICS, "true" );
- cfg.setProperty( Environment.STATEMENT_BATCH_SIZE, "0" );
- }
-
- protected String[] getMappings() {
- return new String[]{
- "ops/Node.hbm.xml",
- "ops/Employer.hbm.xml"
- };
- }
-
- public static Test suite() {
- return new TestSuite( CreateTest.class );
- }
-
- public String getCacheConcurrencyStrategy() {
- return null;
- }
-
-}
-
Copied: trunk/HibernateExt/ejb/src/test/org/hibernate/ejb/test/ops/PersistTest.java (from rev 9647, trunk/HibernateExt/ejb/src/test/org/hibernate/ejb/test/ops/CreateTest.java)
===================================================================
--- trunk/HibernateExt/ejb/src/test/org/hibernate/ejb/test/ops/CreateTest.java 2006-03-17 11:09:10 UTC (rev 9647)
+++ trunk/HibernateExt/ejb/src/test/org/hibernate/ejb/test/ops/PersistTest.java 2006-03-22 23:21:44 UTC (rev 9679)
@@ -0,0 +1,223 @@
+//$Id$
+package org.hibernate.ejb.test.ops;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import org.hibernate.PersistentObjectException;
+import org.hibernate.Session;
+import org.hibernate.Transaction;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.cfg.Environment;
+import org.hibernate.ejb.test.EJB3TestCase;
+import org.hibernate.exception.ConstraintViolationException;
+
+/**
+ * @author Gavin King
+ */
+public class PersistTest extends EJB3TestCase {
+
+ public PersistTest(String str) {
+ super( str );
+ }
+
+ public void testCreateTree() {
+
+ clearCounts();
+
+ Session s = openSession();
+ Transaction tx = s.beginTransaction();
+ Node root = new Node( "root" );
+ Node child = new Node( "child" );
+ root.addChild( child );
+ s.persist( root );
+ tx.commit();
+ s.close();
+
+ assertInsertCount( 2 );
+ assertUpdateCount( 0 );
+
+ s = openSession();
+ tx = s.beginTransaction();
+ root = (Node) s.get( Node.class, "root" );
+ Node child2 = new Node( "child2" );
+ root.addChild( child2 );
+ tx.commit();
+ s.close();
+
+ assertInsertCount( 3 );
+ assertUpdateCount( 0 );
+ }
+
+ public void testCreateTreeWithGeneratedId() {
+
+ clearCounts();
+
+ Session s = openSession();
+ Transaction tx = s.beginTransaction();
+ NumberedNode root = new NumberedNode( "root" );
+ NumberedNode child = new NumberedNode( "child" );
+ root.addChild( child );
+ s.persist( root );
+ tx.commit();
+ s.close();
+
+ assertInsertCount( 2 );
+ assertUpdateCount( 0 );
+
+ s = openSession();
+ tx = s.beginTransaction();
+ root = (NumberedNode) s.get( NumberedNode.class, new Long( root.getId() ) );
+ NumberedNode child2 = new NumberedNode( "child2" );
+ root.addChild( child2 );
+ tx.commit();
+ s.close();
+
+ assertInsertCount( 3 );
+ assertUpdateCount( 0 );
+ }
+
+ public void testCreateException() {
+ Session s = openSession();
+ Transaction tx = s.beginTransaction();
+ Node dupe = new Node( "dupe" );
+ s.persist( dupe );
+ s.persist( dupe );
+ tx.commit();
+ s.close();
+
+ s = openSession();
+ tx = s.beginTransaction();
+ s.persist( dupe );
+ try {
+ tx.commit();
+ fail("Cannot persist() twice the same entity");
+ }
+ catch (ConstraintViolationException cve) {
+ //verify that an exception is thrown!
+ }
+ tx.rollback();
+ s.close();
+
+ Node nondupe = new Node( "nondupe" );
+ nondupe.addChild( dupe );
+
+ s = openSession();
+ tx = s.beginTransaction();
+ s.persist( nondupe );
+ try {
+ tx.commit();
+ assertFalse( true );
+ }
+ catch (ConstraintViolationException cve) {
+ //verify that an exception is thrown!
+ }
+ tx.rollback();
+ s.close();
+ }
+
+ public void testCreateExceptionWithGeneratedId() {
+ Session s = openSession();
+ Transaction tx = s.beginTransaction();
+ NumberedNode dupe = new NumberedNode( "dupe" );
+ s.persist( dupe );
+ s.persist( dupe );
+ tx.commit();
+ s.close();
+
+ s = openSession();
+ tx = s.beginTransaction();
+ try {
+ s.persist( dupe );
+ assertFalse( true );
+ }
+ catch (PersistentObjectException poe) {
+ //verify that an exception is thrown!
+ }
+ tx.rollback();
+ s.close();
+
+ NumberedNode nondupe = new NumberedNode( "nondupe" );
+ nondupe.addChild( dupe );
+
+ s = openSession();
+ tx = s.beginTransaction();
+ try {
+ s.persist( nondupe );
+ assertFalse( true );
+ }
+ catch (PersistentObjectException poe) {
+ //verify that an exception is thrown!
+ }
+ tx.rollback();
+ s.close();
+ }
+
+ public void testBasic() throws Exception {
+ Session s;
+ Transaction tx;
+ s = openSession();
+ tx = s.beginTransaction();
+ Employer er = new Employer();
+ Employee ee = new Employee();
+ s.persist( ee );
+ Collection erColl = new ArrayList();
+ Collection eeColl = new ArrayList();
+ erColl.add( ee );
+ eeColl.add( er );
+ er.setEmployees( erColl );
+ ee.setEmployers( eeColl );
+ tx.commit();
+ s.close();
+
+ s = openSession();
+ tx = s.beginTransaction();
+ er = (Employer) s.load( Employer.class, er.getId() );
+ assertNotNull( er );
+ assertNotNull( er.getEmployees() );
+ assertEquals( 1, er.getEmployees().size() );
+ Employee eeFromDb = (Employee) er.getEmployees().iterator().next();
+ assertEquals( ee.getId(), eeFromDb.getId() );
+ tx.commit();
+ s.close();
+ }
+
+ private void clearCounts() {
+ getSessions().getStatistics().clear();
+ }
+
+ private void assertInsertCount(int count) {
+ int inserts = (int) getSessions().getStatistics().getEntityInsertCount();
+ assertEquals( count, inserts );
+ }
+
+ private void assertUpdateCount(int count) {
+ int updates = (int) getSessions().getStatistics().getEntityUpdateCount();
+ assertEquals( count, updates );
+ }
+
+ protected void configure(Configuration cfg) {
+ super.configure( cfg );
+ cfg.setProperty( Environment.GENERATE_STATISTICS, "true" );
+ cfg.setProperty( Environment.STATEMENT_BATCH_SIZE, "0" );
+ }
+
+ protected String[] getMappings() {
+ return new String[]{
+ "ops/Node.hbm.xml",
+ "ops/Employer.hbm.xml"
+ };
+ }
+
+ public static Test suite() {
+ return new TestSuite( PersistTest.class );
+ }
+
+ public String getCacheConcurrencyStrategy() {
+ return null;
+ }
+
+}
+
Property changes on: trunk/HibernateExt/ejb/src/test/org/hibernate/ejb/test/ops/PersistTest.java
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:keywords
+ Author Date Id Revision
Name: svn:eol-style
+ native
|
|
From: <hib...@li...> - 2006-03-22 22:37:29
|
Author: epbernard
Date: 2006-03-22 17:37:25 -0500 (Wed, 22 Mar 2006)
New Revision: 9678
Added:
trunk/HibernateExt/ejb-api/src/javax/persistence/OptimisticLockException.java
Modified:
trunk/HibernateExt/ejb-api/
Log:
add optimistic lock exception
Property changes on: trunk/HibernateExt/ejb-api
___________________________________________________________________
Name: svn:ignore
- build
.settings
build.properties
+ build
.settings
build.properties
classes
Added: trunk/HibernateExt/ejb-api/src/javax/persistence/OptimisticLockException.java
===================================================================
--- trunk/HibernateExt/ejb-api/src/javax/persistence/OptimisticLockException.java 2006-03-22 22:34:54 UTC (rev 9677)
+++ trunk/HibernateExt/ejb-api/src/javax/persistence/OptimisticLockException.java 2006-03-22 22:37:25 UTC (rev 9678)
@@ -0,0 +1,23 @@
+//$Id: $
+package javax.persistence;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class OptimisticLockException extends PersistenceException {
+ public OptimisticLockException() {
+ super();
+ }
+
+ public OptimisticLockException(Throwable cause) {
+ super( cause );
+ }
+
+ public OptimisticLockException(String message) {
+ super( message );
+ }
+
+ public OptimisticLockException(String message, Throwable cause) {
+ super( message, cause );
+ }
+}
|
|
From: <hib...@li...> - 2006-03-22 22:35:19
|
Author: epbernard
Date: 2006-03-22 17:34:54 -0500 (Wed, 22 Mar 2006)
New Revision: 9677
Modified:
trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/EJB3DTDEntityResolver.java
Log:
style
Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/EJB3DTDEntityResolver.java
===================================================================
--- trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/EJB3DTDEntityResolver.java 2006-03-22 17:38:55 UTC (rev 9676)
+++ trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/EJB3DTDEntityResolver.java 2006-03-22 22:34:54 UTC (rev 9677)
@@ -6,8 +6,8 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.util.DTDEntityResolver;
+import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
-import org.xml.sax.EntityResolver;
/**
* @author Emmanuel Bernard
@@ -17,19 +17,20 @@
private static final Log log = LogFactory.getLog( EJB3DTDEntityResolver.class );
- boolean resolved = false;
+ boolean resolved = false;
- public boolean isResolved()
- {
- return resolved;
- }
+ public boolean isResolved() {
+ return resolved;
+ }
- public InputSource resolveEntity(String publicId, String systemId) {
+ public InputSource resolveEntity(String publicId, String systemId) {
InputSource is = super.resolveEntity( publicId, systemId );
- if (is == null) {
+ if ( is == null ) {
if ( systemId != null ) {
if ( systemId.endsWith( "orm_1_0.xsd" ) ) {
- log.debug( "recognized EJB3 ORM namespace; attempting to resolve on classpath under org/hibernate/ejb" );
+ log.debug(
+ "recognized EJB3 ORM namespace; attempting to resolve on classpath under org/hibernate/ejb"
+ );
String path = "org/hibernate/ejb/" + "orm_1_0.xsd";
InputStream dtdStream = resolveInHibernateNamespace( path );
if ( dtdStream == null ) {
@@ -40,12 +41,14 @@
InputSource source = new InputSource( dtdStream );
source.setPublicId( publicId );
source.setSystemId( systemId );
- resolved = false;
- return source;
+ resolved = false;
+ return source;
}
}
else if ( systemId.endsWith( "persistence_1_0.xsd" ) ) {
- log.debug( "recognized EJB3 ORM namespace; attempting to resolve on classpath under org/hibernate/ejb" );
+ log.debug(
+ "recognized EJB3 ORM namespace; attempting to resolve on classpath under org/hibernate/ejb"
+ );
String path = "org/hibernate/ejb/" + "persistence_1_0.xsd";
InputStream dtdStream = resolveInHibernateNamespace( path );
if ( dtdStream == null ) {
@@ -56,15 +59,15 @@
InputSource source = new InputSource( dtdStream );
source.setPublicId( publicId );
source.setSystemId( systemId );
- resolved = true;
- return source;
+ resolved = true;
+ return source;
}
}
}
}
else {
- resolved = true;
- return is;
+ resolved = true;
+ return is;
}
//use the default behavior
return null;
|
|
From: <hib...@li...> - 2006-03-22 17:39:04
|
Author: ste...@jb...
Date: 2006-03-22 12:38:55 -0500 (Wed, 22 Mar 2006)
New Revision: 9676
Modified:
trunk/Hibernate3/src/org/hibernate/dialect/Oracle9Dialect.java
trunk/Hibernate3/src/org/hibernate/jdbc/AbstractBatcher.java
trunk/Hibernate3/src/org/hibernate/jdbc/Batcher.java
trunk/Hibernate3/src/org/hibernate/persister/entity/AbstractEntityPersister.java
trunk/Hibernate3/src/org/hibernate/util/GetGeneratedKeysHelper.java
Log:
rollback HHH-1160 (getGeneratedKeys passing in pkColumnNames) in favor of HHH-1590
Modified: trunk/Hibernate3/src/org/hibernate/dialect/Oracle9Dialect.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/dialect/Oracle9Dialect.java 2006-03-22 17:34:59 UTC (rev 9675)
+++ trunk/Hibernate3/src/org/hibernate/dialect/Oracle9Dialect.java 2006-03-22 17:38:55 UTC (rev 9676)
@@ -46,6 +46,11 @@
registerColumnType( Types.BLOB, "blob" );
registerColumnType( Types.CLOB, "clob" );
+ // Oracle driver reports to support getGeneratedKeys(), but they only
+ // support the version taking an array of the names of the columns to
+ // be returned (via its RETURNING clause). No other driver seems to
+ // support this overloaded version.
+ getDefaultProperties().setProperty(Environment.USE_GET_GENERATED_KEYS, "false");
getDefaultProperties().setProperty(Environment.USE_STREAMS_FOR_BINARY, "true");
getDefaultProperties().setProperty(Environment.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE);
Modified: trunk/Hibernate3/src/org/hibernate/jdbc/AbstractBatcher.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/jdbc/AbstractBatcher.java 2006-03-22 17:34:59 UTC (rev 9675)
+++ trunk/Hibernate3/src/org/hibernate/jdbc/AbstractBatcher.java 2006-03-22 17:38:55 UTC (rev 9676)
@@ -83,41 +83,69 @@
public PreparedStatement prepareStatement(String sql)
throws SQLException, HibernateException {
- return prepareStatement( sql, false, null );
+ return prepareStatement( sql, false );
}
- public PreparedStatement prepareStatement(String sql, boolean getGeneratedKeys, String[] pkColumnNames)
- throws SQLException, HibernateException {
+ public PreparedStatement prepareStatement(String sql, boolean getGeneratedKeys)
+ throws SQLException, HibernateException {
executeBatch();
logOpenPreparedStatement();
- return getPreparedStatement( connectionManager.getConnection(), sql, false, getGeneratedKeys, pkColumnNames, null, false );
+ return getPreparedStatement(
+ connectionManager.getConnection(),
+ sql,
+ false,
+ getGeneratedKeys,
+ null,
+ false
+ );
}
- public PreparedStatement prepareSelectStatement(String sql)
- throws SQLException, HibernateException {
+ public PreparedStatement prepareSelectStatement(String sql)
+ throws SQLException, HibernateException {
logOpenPreparedStatement();
- return getPreparedStatement( connectionManager.getConnection(), sql, false, false, null, null, false );
+ return getPreparedStatement(
+ connectionManager.getConnection(),
+ sql,
+ false,
+ false,
+ null,
+ false
+ );
}
- public PreparedStatement prepareQueryStatement(String sql, boolean scrollable, ScrollMode scrollMode)
- throws SQLException, HibernateException {
+ public PreparedStatement prepareQueryStatement(
+ String sql,
+ boolean scrollable,
+ ScrollMode scrollMode) throws SQLException, HibernateException {
logOpenPreparedStatement();
- PreparedStatement ps = getPreparedStatement( connectionManager.getConnection(), sql, scrollable, scrollMode );
- setStatementFetchSize(ps);
- statementsToClose.add(ps);
- lastQuery=ps;
+ PreparedStatement ps = getPreparedStatement(
+ connectionManager.getConnection(),
+ sql,
+ scrollable,
+ scrollMode
+ );
+ setStatementFetchSize( ps );
+ statementsToClose.add( ps );
+ lastQuery = ps;
return ps;
}
- public CallableStatement prepareCallableQueryStatement(String sql, boolean scrollable, ScrollMode scrollMode)
- throws SQLException, HibernateException {
+ public CallableStatement prepareCallableQueryStatement(
+ String sql,
+ boolean scrollable,
+ ScrollMode scrollMode) throws SQLException, HibernateException {
logOpenPreparedStatement();
- CallableStatement ps = (CallableStatement) getPreparedStatement(
- connectionManager.getConnection(), sql, scrollable, false, null, scrollMode, true
+ CallableStatement ps = ( CallableStatement ) getPreparedStatement(
+ connectionManager.getConnection(),
+ sql,
+ scrollable,
+ false,
+ scrollMode,
+ true
);
- setStatementFetchSize(ps);
- statementsToClose.add(ps);
- lastQuery=ps;
+ setStatementFetchSize( ps );
+ statementsToClose.add( ps );
+ lastQuery = ps;
return ps;
}
@@ -163,8 +191,8 @@
}
}
- public PreparedStatement prepareBatchStatement(String sql)
- throws SQLException, HibernateException {
+ public PreparedStatement prepareBatchStatement(String sql)
+ throws SQLException, HibernateException {
sql = getSQL( sql );
if ( !sql.equals(batchUpdateSQL) ) {
@@ -178,8 +206,8 @@
return batchUpdate;
}
- public CallableStatement prepareBatchCallableStatement(String sql)
- throws SQLException, HibernateException {
+ public CallableStatement prepareBatchCallableStatement(String sql)
+ throws SQLException, HibernateException {
if ( !sql.equals(batchUpdateSQL) ) { // TODO: what if batchUpdate is a callablestatement ?
batchUpdate=prepareCallableStatement(sql); // calls executeBatch()
batchUpdateSQL=sql;
@@ -365,36 +393,44 @@
final boolean scrollable,
final ScrollMode scrollMode)
throws SQLException {
- return getPreparedStatement(conn, sql, scrollable, false, null, scrollMode, false);
+ return getPreparedStatement(
+ conn,
+ sql,
+ scrollable,
+ false,
+ scrollMode,
+ false
+ );
}
- private CallableStatement getCallableStatement( final Connection conn,
+ private CallableStatement getCallableStatement(
+ final Connection conn,
String sql,
- boolean scrollable)
- throws SQLException {
-
+ boolean scrollable) throws SQLException {
if ( scrollable && !factory.getSettings().isScrollableResultSetsEnabled() ) {
throw new AssertionFailure("scrollable result sets are not enabled");
}
sql = getSQL( sql );
+ log( sql );
- log(sql);
-
log.trace("preparing callable statement");
- if (scrollable) {
- return conn.prepareCall(sql, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
+ if ( scrollable ) {
+ return conn.prepareCall(
+ sql,
+ ResultSet.TYPE_SCROLL_INSENSITIVE,
+ ResultSet.CONCUR_READ_ONLY
+ );
}
else {
- return conn.prepareCall(sql);
+ return conn.prepareCall( sql );
}
-
}
private String getSQL(String sql) {
- sql = interceptor.onPrepareStatement(sql);
- if(sql==null || sql.length()==0) {
- throw new AssertionFailure("Interceptor.onPrepareStatement() returned null or empty string.");
+ sql = interceptor.onPrepareStatement( sql );
+ if ( sql==null || sql.length() == 0 ) {
+ throw new AssertionFailure( "Interceptor.onPrepareStatement() returned null or empty string." );
}
return sql;
}
@@ -404,42 +440,37 @@
String sql,
boolean scrollable,
final boolean useGetGeneratedKeys,
- final String[] pkColumnNames,
final ScrollMode scrollMode,
- final boolean callable)
- throws SQLException {
-
+ final boolean callable) throws SQLException {
if ( scrollable && !factory.getSettings().isScrollableResultSetsEnabled() ) {
throw new AssertionFailure("scrollable result sets are not enabled");
}
-
if ( useGetGeneratedKeys && !factory.getSettings().isGetGeneratedKeysEnabled() ) {
throw new AssertionFailure("getGeneratedKeys() support is not enabled");
}
sql = getSQL( sql );
-
- log(sql);
+ log( sql );
- log.trace("preparing statement");
+ log.trace( "preparing statement" );
PreparedStatement result;
- if (scrollable) {
- if (callable) {
+ if ( scrollable ) {
+ if ( callable ) {
result = conn.prepareCall( sql, scrollMode.toResultSetType(), ResultSet.CONCUR_READ_ONLY );
}
else {
result = conn.prepareStatement( sql, scrollMode.toResultSetType(), ResultSet.CONCUR_READ_ONLY );
}
}
- else if (useGetGeneratedKeys) {
- result = GetGeneratedKeysHelper.prepareStatement( conn, sql, pkColumnNames );
+ else if ( useGetGeneratedKeys ) {
+ result = GetGeneratedKeysHelper.prepareStatement( conn, sql );
}
else {
- if (callable) {
- result = conn.prepareCall(sql);
+ if ( callable ) {
+ result = conn.prepareCall( sql );
}
else {
- result = conn.prepareStatement(sql);
+ result = conn.prepareStatement( sql );
}
}
Modified: trunk/Hibernate3/src/org/hibernate/jdbc/Batcher.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/jdbc/Batcher.java 2006-03-22 17:34:59 UTC (rev 9675)
+++ trunk/Hibernate3/src/org/hibernate/jdbc/Batcher.java 2006-03-22 17:38:55 UTC (rev 9676)
@@ -50,7 +50,7 @@
* Get a non-batchable prepared statement to use for inserting / deleting / updating.
* Must be explicitly released by <tt>closeStatement()</tt>
*/
- public PreparedStatement prepareStatement(String sql, boolean useGetGeneratedKeys, String[] keyColumnNames) throws SQLException, HibernateException;
+ public PreparedStatement prepareStatement(String sql, boolean useGetGeneratedKeys) throws SQLException, HibernateException;
/**
* Get a non-batchable prepared statement to use for inserting / deleting / updating.
* Must be explicitly released by <tt>closeStatement()</tt>
Modified: trunk/Hibernate3/src/org/hibernate/persister/entity/AbstractEntityPersister.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/persister/entity/AbstractEntityPersister.java 2006-03-22 17:34:59 UTC (rev 9675)
+++ trunk/Hibernate3/src/org/hibernate/persister/entity/AbstractEntityPersister.java 2006-03-22 17:38:55 UTC (rev 9676)
@@ -2084,7 +2084,7 @@
try {
//do the insert
- PreparedStatement insert = session.getBatcher().prepareStatement( sql, useGetGeneratedKeys(), getKeyColumnNames() );
+ PreparedStatement insert = session.getBatcher().prepareStatement( sql, useGetGeneratedKeys() );
try {
dehydrate( null, fields, notNull, propertyColumnInsertable, 0, insert, session );
Modified: trunk/Hibernate3/src/org/hibernate/util/GetGeneratedKeysHelper.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/util/GetGeneratedKeysHelper.java 2006-03-22 17:34:59 UTC (rev 9675)
+++ trunk/Hibernate3/src/org/hibernate/util/GetGeneratedKeysHelper.java 2006-03-22 17:38:55 UTC (rev 9676)
@@ -19,14 +19,19 @@
private GetGeneratedKeysHelper() {
}
+ private static final Integer RETURN_GENERATED_KEYS;
private static final Method PREPARE_STATEMENT_METHOD;
private static final Method GET_GENERATED_KEYS_METHOD;
static {
try {
+ int returnGeneratedKeysEnumValue = Statement.class
+ .getDeclaredField( "RETURN_GENERATED_KEYS" )
+ .getInt( PreparedStatement.class );
+ RETURN_GENERATED_KEYS = new Integer( returnGeneratedKeysEnumValue );
PREPARE_STATEMENT_METHOD = Connection.class.getMethod(
"prepareStatement",
- new Class[] { String.class, String[].class }
+ new Class[] { String.class, Integer.TYPE }
);
GET_GENERATED_KEYS_METHOD = Statement.class.getDeclaredMethod(
"getGeneratedKeys",
@@ -38,9 +43,8 @@
}
}
- public static PreparedStatement prepareStatement(Connection conn, String sql, String[] pkColumnNames)
- throws SQLException {
- Object[] args = new Object[] {sql, pkColumnNames};
+ public static PreparedStatement prepareStatement(Connection conn, String sql) throws SQLException {
+ Object[] args = new Object[] { sql, RETURN_GENERATED_KEYS } ;
try {
return ( PreparedStatement ) PREPARE_STATEMENT_METHOD.invoke( conn, args );
}
|
|
From: <hib...@li...> - 2006-03-22 17:35:12
|
Author: ste...@jb...
Date: 2006-03-22 12:34:59 -0500 (Wed, 22 Mar 2006)
New Revision: 9675
Modified:
trunk/Hibernate3/test/org/hibernate/test/generatedkeys/oracle/MyEntity.hbm.xml
trunk/Hibernate3/test/org/hibernate/test/generatedkeys/oracle/OracleGeneratedKeysTest.java
Log:
HHH-1592 : SelectGenerator & natural-id
Modified: trunk/Hibernate3/test/org/hibernate/test/generatedkeys/oracle/MyEntity.hbm.xml
===================================================================
--- trunk/Hibernate3/test/org/hibernate/test/generatedkeys/oracle/MyEntity.hbm.xml 2006-03-22 17:31:13 UTC (rev 9674)
+++ trunk/Hibernate3/test/org/hibernate/test/generatedkeys/oracle/MyEntity.hbm.xml 2006-03-22 17:34:59 UTC (rev 9675)
@@ -10,7 +10,9 @@
<id name="id">
<generator class="select"/>
</id>
- <property name="name"/>
+ <natural-id>
+ <property name="name"/>
+ </natural-id>
</class>
<database-object>
Modified: trunk/Hibernate3/test/org/hibernate/test/generatedkeys/oracle/OracleGeneratedKeysTest.java
===================================================================
--- trunk/Hibernate3/test/org/hibernate/test/generatedkeys/oracle/OracleGeneratedKeysTest.java 2006-03-22 17:31:13 UTC (rev 9674)
+++ trunk/Hibernate3/test/org/hibernate/test/generatedkeys/oracle/OracleGeneratedKeysTest.java 2006-03-22 17:34:59 UTC (rev 9675)
@@ -20,7 +20,6 @@
protected void configure(Configuration cfg) {
super.configure( cfg );
- cfg.setProperty( Environment.USE_GET_GENERATED_KEYS, "true" ); // make certain generated keys enabled.
}
public boolean appliesTo(Dialect dialect) {
|
|
From: <hib...@li...> - 2006-03-22 17:31:18
|
Author: ste...@jb...
Date: 2006-03-22 12:31:13 -0500 (Wed, 22 Mar 2006)
New Revision: 9674
Modified:
trunk/Hibernate3/src/org/hibernate/id/SelectGenerator.java
Log:
HHH-1592 : SelectGenerator & natural-id
Modified: trunk/Hibernate3/src/org/hibernate/id/SelectGenerator.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/id/SelectGenerator.java 2006-03-22 14:57:59 UTC (rev 9673)
+++ trunk/Hibernate3/src/org/hibernate/id/SelectGenerator.java 2006-03-22 17:31:13 UTC (rev 9674)
@@ -34,29 +34,66 @@
}
protected String getSQL(PostInsertIdentityPersister persister) {
- return persister.getSelectByUniqueKeyString(uniqueKeyPropertyName);
+ if ( entityName == null ) {
+ entityName = persister.getEntityName();
+ }
+ if ( uniqueKeyPropertyName == null ) {
+ int[] naturalIdPropertyIndices = persister.getNaturalIdentifierProperties();
+ if ( naturalIdPropertyIndices == null ){
+ throw new IdentifierGenerationException(
+ "no natural-id property defined; need to specify [key] in " +
+ "generator parameters"
+ );
+ }
+ if ( naturalIdPropertyIndices.length > 1 ) {
+ throw new IdentifierGenerationException(
+ "select generator does not currently support composite " +
+ "natural-id properties; need to specify [key] in generator parameters"
+ );
+ }
+ if ( persister.getPropertyInsertGeneration() [ naturalIdPropertyIndices[0] ] ) {
+ throw new IdentifierGenerationException(
+ "natural-id also defined as insert-generated; need to specify [key] " +
+ "in generator parameters"
+ );
+ }
+ uniqueKeyPropertyName = persister.getPropertyNames() [ naturalIdPropertyIndices[0] ];
+ }
+ return persister.getSelectByUniqueKeyString( uniqueKeyPropertyName );
}
- protected void bindParameters(SessionImplementor session, PreparedStatement ps, Object object, PostInsertIdentityPersister persister)
- throws SQLException {
+ protected void bindParameters(
+ SessionImplementor session,
+ PreparedStatement ps,
+ Object object,
+ PostInsertIdentityPersister persister) throws SQLException {
Type uniqueKeyPropertyType = session.getFactory()
- .getClassMetadata(entityName)
- .getPropertyType(uniqueKeyPropertyName);
- Object uniqueKeyValue = persister.getPropertyValue( object, uniqueKeyPropertyName, session.getEntityMode() );
+ .getClassMetadata( entityName )
+ .getPropertyType( uniqueKeyPropertyName );
+ Object uniqueKeyValue = persister.getPropertyValue(
+ object,
+ uniqueKeyPropertyName,
+ session.getEntityMode()
+ );
uniqueKeyPropertyType.nullSafeSet( ps, uniqueKeyValue, 1, session );
}
- protected Serializable getResult(SessionImplementor session, ResultSet rs, Object object, PostInsertIdentityPersister persister)
- throws SQLException {
+ protected Serializable getResult(
+ SessionImplementor session,
+ ResultSet rs,
+ Object object,
+ PostInsertIdentityPersister persister) throws SQLException {
if ( !rs.next() ) {
- throw new IdentifierGenerationException( "the inserted row could not be located by the unique key: " + uniqueKeyPropertyName );
+ throw new IdentifierGenerationException(
+ "the inserted row could not be located by the unique key: " +
+ uniqueKeyPropertyName
+ );
}
- return (Serializable) idType.nullSafeGet(rs, persister.getRootTableKeyColumnNames(), session, object);
+ return ( Serializable ) idType.nullSafeGet(
+ rs,
+ persister.getRootTableKeyColumnNames(),
+ session,
+ object
+ );
}
}
-
-
-
-
-
-
|
|
From: <hib...@li...> - 2006-03-22 14:58:14
|
Author: ste...@jb...
Date: 2006-03-22 09:57:59 -0500 (Wed, 22 Mar 2006)
New Revision: 9673
Added:
trunk/Hibernate3/src/org/hibernate/action/DelayedPostInsertIdentifier.java
trunk/Hibernate3/test/org/hibernate/test/generatedkeys/identity/
trunk/Hibernate3/test/org/hibernate/test/generatedkeys/identity/IdentityGeneratedKeysTest.java
trunk/Hibernate3/test/org/hibernate/test/generatedkeys/identity/MyChild.java
trunk/Hibernate3/test/org/hibernate/test/generatedkeys/identity/MyEntity.hbm.xml
trunk/Hibernate3/test/org/hibernate/test/generatedkeys/identity/MyEntity.java
trunk/Hibernate3/test/org/hibernate/test/generatedkeys/identity/MySibling.java
Modified:
trunk/Hibernate3/src/org/hibernate/action/CollectionAction.java
trunk/Hibernate3/src/org/hibernate/action/EntityAction.java
trunk/Hibernate3/src/org/hibernate/action/EntityIdentityInsertAction.java
trunk/Hibernate3/src/org/hibernate/engine/PersistenceContext.java
trunk/Hibernate3/src/org/hibernate/engine/StatefulPersistenceContext.java
trunk/Hibernate3/src/org/hibernate/event/def/AbstractSaveEventListener.java
trunk/Hibernate3/src/org/hibernate/event/def/DefaultFlushEntityEventListener.java
trunk/Hibernate3/src/org/hibernate/event/def/DefaultMergeEventListener.java
trunk/Hibernate3/src/org/hibernate/event/def/DefaultPersistEventListener.java
trunk/Hibernate3/src/org/hibernate/event/def/DefaultReplicateEventListener.java
trunk/Hibernate3/src/org/hibernate/event/def/DefaultSaveOrUpdateEventListener.java
trunk/Hibernate3/test/org/hibernate/test/tm/CMTTest.java
Log:
HHH-1588 : delay post-insert-identifier-generator insertions on persist() outside of transaction
Modified: trunk/Hibernate3/src/org/hibernate/action/CollectionAction.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/action/CollectionAction.java 2006-03-22 13:11:03 UTC (rev 9672)
+++ trunk/Hibernate3/src/org/hibernate/action/CollectionAction.java 2006-03-22 14:57:59 UTC (rev 9673)
@@ -22,6 +22,7 @@
private transient CollectionPersister persister;
private final Serializable key;
+ private Serializable finalKey;
private final SessionImplementor session;
private SoftLock lock;
private final String collectionRole;
@@ -75,7 +76,16 @@
}
protected final Serializable getKey() {
- return key;
+ finalKey = key;
+ if ( key instanceof DelayedPostInsertIdentifier ) {
+ // need to look it up from the persistence-context
+ finalKey = session.getPersistenceContext().getEntry( collection.getOwner() ).getId();
+ if ( finalKey == key ) {
+ // we may be screwed here since the collection action is about to execute
+ // and we do not know the final owner key value
+ }
+ }
+ return finalKey;
}
protected final SessionImplementor getSession() {
Added: trunk/Hibernate3/src/org/hibernate/action/DelayedPostInsertIdentifier.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/action/DelayedPostInsertIdentifier.java 2006-03-22 13:11:03 UTC (rev 9672)
+++ trunk/Hibernate3/src/org/hibernate/action/DelayedPostInsertIdentifier.java 2006-03-22 14:57:59 UTC (rev 9673)
@@ -0,0 +1,49 @@
+package org.hibernate.action;
+
+import java.io.Serializable;
+
+/**
+ * Acts as a stand-in for an entity identifier which is supposed to be
+ * generated on insert (like an IDENTITY column) where the insert needed to
+ * be delayed because we were outside a transaction when the persist
+ * occurred (save currently still performs the insert).
+ * <p/>
+ * The stand-in is only used within the {@link org.hibernate.engine.PersistenceContext}
+ * in order to distinguish one instance from another; it is never injected into
+ * the entity instance or returned to the client...
+ *
+ * @author Steve Ebersole
+ */
+public class DelayedPostInsertIdentifier implements Serializable {
+ private static long SEQUENCE = 0;
+ private final long sequence;
+
+ public DelayedPostInsertIdentifier() {
+ synchronized( DelayedPostInsertIdentifier.class ) {
+ if ( SEQUENCE == Long.MAX_VALUE ) {
+ SEQUENCE = 0;
+ }
+ this.sequence = SEQUENCE++;
+ }
+ }
+
+ public boolean equals(Object o) {
+ if ( this == o ) {
+ return true;
+ }
+ if ( o == null || getClass() != o.getClass() ) {
+ return false;
+ }
+ final DelayedPostInsertIdentifier that = ( DelayedPostInsertIdentifier ) o;
+ return sequence == that.sequence;
+ }
+
+ public int hashCode() {
+ return ( int ) ( sequence ^ ( sequence >>> 32 ) );
+ }
+
+ public String toString() {
+ return "<delayed:" + sequence + ">";
+
+ }
+}
Modified: trunk/Hibernate3/src/org/hibernate/action/EntityAction.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/action/EntityAction.java 2006-03-22 13:11:03 UTC (rev 9672)
+++ trunk/Hibernate3/src/org/hibernate/action/EntityAction.java 2006-03-22 14:57:59 UTC (rev 9673)
@@ -47,6 +47,9 @@
}
protected final Serializable getId() {
+ if ( id instanceof DelayedPostInsertIdentifier ) {
+ return session.getPersistenceContext().getEntry( instance ).getId();
+ }
return id;
}
Modified: trunk/Hibernate3/src/org/hibernate/action/EntityIdentityInsertAction.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/action/EntityIdentityInsertAction.java 2006-03-22 13:11:03 UTC (rev 9672)
+++ trunk/Hibernate3/src/org/hibernate/action/EntityIdentityInsertAction.java 2006-03-22 14:57:59 UTC (rev 9673)
@@ -4,7 +4,9 @@
import java.io.Serializable;
import org.hibernate.HibernateException;
+import org.hibernate.AssertionFailure;
import org.hibernate.engine.SessionImplementor;
+import org.hibernate.engine.EntityKey;
import org.hibernate.event.PostInsertEvent;
import org.hibernate.event.PostInsertEventListener;
import org.hibernate.event.PreInsertEvent;
@@ -13,13 +15,21 @@
public final class EntityIdentityInsertAction extends EntityAction {
private final Object[] state;
+ private final boolean isDelayed;
+ private final EntityKey delayedEntityKey;
//private CacheEntry cacheEntry;
private Serializable generatedId;
- public EntityIdentityInsertAction(Object[] state, Object instance, EntityPersister persister, SessionImplementor session)
- throws HibernateException {
+ public EntityIdentityInsertAction(
+ Object[] state,
+ Object instance,
+ EntityPersister persister,
+ SessionImplementor session,
+ boolean isDelayed) throws HibernateException {
super( session, null, instance, persister );
this.state = state;
+ this.isDelayed = isDelayed;
+ delayedEntityKey = isDelayed ? generateDelayedEntityKey() : null;
}
public void execute() throws HibernateException {
@@ -62,6 +72,9 @@
}
private void postInsert() {
+ if ( isDelayed ) {
+ getSession().getPersistenceContext().replaceDelayedEntityIdentityInsertKeys( delayedEntityKey, generatedId );
+ }
PostInsertEventListener[] postListeners = getSession().getListeners()
.getPostInsertEventListeners();
if (postListeners.length>0) {
@@ -120,11 +133,14 @@
return generatedId;
}
+ public EntityKey getDelayedEntityKey() {
+ return delayedEntityKey;
+ }
+
+ private synchronized EntityKey generateDelayedEntityKey() {
+ if ( !isDelayed ) {
+ throw new AssertionFailure( "cannot request delayed entity-key for non-delayed post-insert-id generation" );
+ }
+ return new EntityKey( new DelayedPostInsertIdentifier(), getPersister(), getSession().getEntityMode() );
+ }
}
-
-
-
-
-
-
-
Modified: trunk/Hibernate3/src/org/hibernate/engine/PersistenceContext.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/engine/PersistenceContext.java 2006-03-22 13:11:03 UTC (rev 9672)
+++ trunk/Hibernate3/src/org/hibernate/engine/PersistenceContext.java 2006-03-22 14:57:59 UTC (rev 9673)
@@ -431,4 +431,5 @@
*/
public void setReadOnly(Object entity, boolean readOnly);
+ void replaceDelayedEntityIdentityInsertKeys(EntityKey oldKey, Serializable generatedId);
}
\ No newline at end of file
Modified: trunk/Hibernate3/src/org/hibernate/engine/StatefulPersistenceContext.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/engine/StatefulPersistenceContext.java 2006-03-22 13:11:03 UTC (rev 9672)
+++ trunk/Hibernate3/src/org/hibernate/engine/StatefulPersistenceContext.java 2006-03-22 14:57:59 UTC (rev 9673)
@@ -1098,6 +1098,27 @@
hasNonReadOnlyEntities = hasNonReadOnlyEntities || !readOnly;
}
+ public void replaceDelayedEntityIdentityInsertKeys(EntityKey oldKey, Serializable generatedId) {
+ Object entity = entitiesByKey.remove( oldKey );
+ EntityEntry oldEntry = ( EntityEntry ) entityEntries.remove( entity );
+
+ EntityKey newKey = new EntityKey( generatedId, oldEntry.getPersister(), getSession().getEntityMode() );
+ addEntity( newKey, entity );
+ addEntry(
+ entity,
+ oldEntry.getStatus(),
+ oldEntry.getLoadedState(),
+ oldEntry.getRowId(),
+ generatedId,
+ oldEntry.getVersion(),
+ oldEntry.getLockMode(),
+ oldEntry.isExistsInDatabase(),
+ oldEntry.getPersister(),
+ oldEntry.isBeingReplicated(),
+ oldEntry.isLoadedWithLazyPropertiesUnfetched()
+ );
+ }
+
/**
* Used by the owning session to explicitly control serialization of the
* persistence context.
Modified: trunk/Hibernate3/src/org/hibernate/event/def/AbstractSaveEventListener.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/event/def/AbstractSaveEventListener.java 2006-03-22 13:11:03 UTC (rev 9672)
+++ trunk/Hibernate3/src/org/hibernate/event/def/AbstractSaveEventListener.java 2006-03-22 14:57:59 UTC (rev 9673)
@@ -67,22 +67,30 @@
source.getEntityPersister(entityName, entity),
false,
anything,
- source
+ source,
+ true
);
}
/**
* Prepares the save call using a newly generated id.
* @param entity The entity to be saved
+ * @param entityName The entity-name for the entity to be saved
* @param source The session which is the source of this save event.
- * @return The id used to save the entity
+ * @param requiresImmediateIdAccess does the event context require
+ * access to the identifier immediately after execution of this method (if
+ * not, post-insert style id generators may be postponed if we are outside
+ * a transaction).
+ * @return The id used to save the entity; may be null depending on the
+ * type of id generator used and the requiresImmediateIdAccess value
* @throws HibernateException
*/
protected Serializable saveWithGeneratedId(
Object entity,
String entityName,
Object anything,
- EventSource source)
+ EventSource source,
+ boolean requiresImmediateIdAccess)
throws HibernateException {
EntityPersister persister = source.getEntityPersister(entityName, entity);
@@ -97,7 +105,7 @@
return source.getIdentifier( entity );
}
else if ( generatedId == IdentifierGeneratorFactory.POST_INSERT_INDICATOR ) {
- return performSave(entity, null, persister, true, anything, source);
+ return performSave( entity, null, persister, true, anything, source, requiresImmediateIdAccess );
}
else {
@@ -110,7 +118,7 @@
);
}
- return performSave(entity, generatedId, persister, false, anything, source);
+ return performSave( entity, generatedId, persister, false, anything, source, true );
}
}
@@ -122,7 +130,12 @@
* @param persister The entity's persister instance.
* @param useIdentityColumn Is an identity column in use?
* @param source The session from which the event originated.
- * @return The id used to save the entity.
+ * @param requiresImmediateIdAccess does the event context require
+ * access to the identifier immediately after execution of this method (if
+ * not, post-insert style id generators may be postponed if we are outside
+ * a transaction).
+ * @return The id used to save the entity; may be null depending on the
+ * type of id generator used and the requiresImmediateIdAccess value
* @throws HibernateException
*/
protected Serializable performSave(
@@ -131,7 +144,8 @@
EntityPersister persister,
boolean useIdentityColumn,
Object anything,
- EventSource source)
+ EventSource source,
+ boolean requiresImmediateIdAccess)
throws HibernateException {
if ( log.isTraceEnabled() ) {
@@ -169,7 +183,8 @@
persister,
useIdentityColumn,
anything,
- source
+ source,
+ requiresImmediateIdAccess
);
}
@@ -200,7 +215,8 @@
* @param persister The entity's persister instance.
* @param useIdentityColumn Should an identity column be used for id generation?
* @param source The session which is the source of the current event.
- * @return The id used to save the entity.
+ * @return The id used to save the entity; may be null depending on the
+ * type of id generator used and the requiresImmediateIdAccess value
* @throws HibernateException
*/
protected Serializable performSaveOrReplicate(
@@ -209,14 +225,18 @@
EntityPersister persister,
boolean useIdentityColumn,
Object anything,
- EventSource source)
+ EventSource source,
+ boolean requiresImmediateIdAccess)
throws HibernateException {
validate( entity, persister, source );
Serializable id = key==null ? null : key.getIdentifier();
- if (useIdentityColumn) {
+ boolean inTxn = source.getJDBCContext().isTransactionInProgress();
+ boolean shouldDelayIdentityInserts = !inTxn && !requiresImmediateIdAccess;
+
+ if ( useIdentityColumn && !shouldDelayIdentityInserts ) {
log.trace("executing insertions");
source.getActionQueue().executeInserts();
}
@@ -263,15 +283,23 @@
.nullifyTransientReferences(values, types);
new Nullability(source).checkNullability( values, persister, false );
- if (useIdentityColumn) {
- EntityIdentityInsertAction insert = new EntityIdentityInsertAction(values, entity, persister, source);
- source.getActionQueue().execute(insert);
- id = insert.getGeneratedId();
- //now done in EntityIdentityInsertAction
- //persister.setIdentifier( entity, id, source.getEntityMode() );
- key = new EntityKey( id, persister, source.getEntityMode() );
- source.getPersistenceContext().checkUniqueness(key, entity);
- //source.getBatcher().executeBatch(); //found another way to ensure that all batched joined inserts have been executed
+ if ( useIdentityColumn ) {
+ EntityIdentityInsertAction insert = new EntityIdentityInsertAction( values, entity, persister, source, shouldDelayIdentityInserts );
+ if ( ! shouldDelayIdentityInserts ) {
+ log.debug( "executing identity-insert immediately" );
+ source.getActionQueue().execute(insert);
+ id = insert.getGeneratedId();
+ //now done in EntityIdentityInsertAction
+ //persister.setIdentifier( entity, id, source.getEntityMode() );
+ key = new EntityKey( id, persister, source.getEntityMode() );
+ source.getPersistenceContext().checkUniqueness(key, entity);
+ //source.getBatcher().executeBatch(); //found another way to ensure that all batched joined inserts have been executed
+ }
+ else {
+ log.debug( "delaying identity-insert due to no transaction in progress" );
+ source.getActionQueue().addAction( insert );
+ key = insert.getDelayedEntityKey();
+ }
}
Object version = Versioning.getVersion(values, persister);
Modified: trunk/Hibernate3/src/org/hibernate/event/def/DefaultFlushEntityEventListener.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/event/def/DefaultFlushEntityEventListener.java 2006-03-22 13:11:03 UTC (rev 9672)
+++ trunk/Hibernate3/src/org/hibernate/event/def/DefaultFlushEntityEventListener.java 2006-03-22 14:57:59 UTC (rev 9673)
@@ -10,6 +10,7 @@
import org.hibernate.HibernateException;
import org.hibernate.StaleObjectStateException;
import org.hibernate.action.EntityUpdateAction;
+import org.hibernate.action.DelayedPostInsertIdentifier;
import org.hibernate.classic.Validatable;
import org.hibernate.engine.EntityEntry;
import org.hibernate.engine.EntityKey;
@@ -41,6 +42,12 @@
public void checkId(Object object, EntityPersister persister, Serializable id, EntityMode entityMode)
throws HibernateException {
+ if ( id != null && id instanceof DelayedPostInsertIdentifier ) {
+ // this is a situation where the entity id is assigned by a post-insert generator
+ // and was saved outside the transaction forcing it to be delayed
+ return;
+ }
+
if ( persister.canExtractIdOutOfEntity() ) {
Serializable oid = persister.getIdentifier( object, entityMode );
Modified: trunk/Hibernate3/src/org/hibernate/event/def/DefaultMergeEventListener.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/event/def/DefaultMergeEventListener.java 2006-03-22 13:11:03 UTC (rev 9672)
+++ trunk/Hibernate3/src/org/hibernate/event/def/DefaultMergeEventListener.java 2006-03-22 14:57:59 UTC (rev 9673)
@@ -162,10 +162,10 @@
//graphs, since it helps ensure uniqueness
final Serializable requestedId = event.getRequestedId();
if (requestedId==null) {
- saveWithGeneratedId(copy, entityName, copyCache, source);
+ saveWithGeneratedId( copy, entityName, copyCache, source, false );
}
else {
- saveWithRequestedId(copy, requestedId, entityName, copyCache, source);
+ saveWithRequestedId( copy, requestedId, entityName, copyCache, source );
}
// cascade first, so that all unsaved objects get their
Modified: trunk/Hibernate3/src/org/hibernate/event/def/DefaultPersistEventListener.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/event/def/DefaultPersistEventListener.java 2006-03-22 13:11:03 UTC (rev 9672)
+++ trunk/Hibernate3/src/org/hibernate/event/def/DefaultPersistEventListener.java 2006-03-22 14:57:59 UTC (rev 9673)
@@ -128,7 +128,7 @@
final Object entity = source.getPersistenceContext().unproxy( event.getObject() );
if ( createCache.put(entity, entity)==null ) {
- saveWithGeneratedId( entity, event.getEntityName(), createCache, source );
+ saveWithGeneratedId( entity, event.getEntityName(), createCache, source, false );
}
}
Modified: trunk/Hibernate3/src/org/hibernate/event/def/DefaultReplicateEventListener.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/event/def/DefaultReplicateEventListener.java 2006-03-22 13:11:03 UTC (rev 9672)
+++ trunk/Hibernate3/src/org/hibernate/event/def/DefaultReplicateEventListener.java 2006-03-22 14:57:59 UTC (rev 9673)
@@ -120,7 +120,8 @@
persister,
regenerate,
replicationMode,
- source
+ source,
+ true
);
}
Modified: trunk/Hibernate3/src/org/hibernate/event/def/DefaultSaveOrUpdateEventListener.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/event/def/DefaultSaveOrUpdateEventListener.java 2006-03-22 13:11:03 UTC (rev 9672)
+++ trunk/Hibernate3/src/org/hibernate/event/def/DefaultSaveOrUpdateEventListener.java 2006-03-22 14:57:59 UTC (rev 9673)
@@ -187,7 +187,8 @@
event.getEntity(),
event.getEntityName(),
null,
- event.getSession()
+ event.getSession(),
+ true
);
}
Added: trunk/Hibernate3/test/org/hibernate/test/generatedkeys/identity/IdentityGeneratedKeysTest.java
===================================================================
--- trunk/Hibernate3/test/org/hibernate/test/generatedkeys/identity/IdentityGeneratedKeysTest.java 2006-03-22 13:11:03 UTC (rev 9672)
+++ trunk/Hibernate3/test/org/hibernate/test/generatedkeys/identity/IdentityGeneratedKeysTest.java 2006-03-22 14:57:59 UTC (rev 9673)
@@ -0,0 +1,159 @@
+package org.hibernate.test.generatedkeys.identity;
+
+import org.hibernate.test.DatabaseSpecificTestCase;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.Session;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.cfg.Environment;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * @author Steve Ebersole
+ */
+public class IdentityGeneratedKeysTest extends DatabaseSpecificTestCase {
+ public IdentityGeneratedKeysTest(String name) {
+ super( name );
+ }
+
+ protected void configure(Configuration cfg) {
+ super.configure( cfg );
+ cfg.setProperty( Environment.GENERATE_STATISTICS, "true" );
+ }
+
+ protected String[] getMappings() {
+ return new String[] { "generatedkeys/identity/MyEntity.hbm.xml" };
+ }
+
+ public boolean appliesTo(Dialect dialect) {
+ return dialect.supportsIdentityColumns();
+ }
+
+ public static Test suite() {
+ return new TestSuite( IdentityGeneratedKeysTest.class );
+ }
+
+ public void testIdentityColumnGeneratedIds() {
+ Session s = openSession();
+ s.beginTransaction();
+ MyEntity myEntity = new MyEntity( "test" );
+ Long id = ( Long ) s.save( myEntity );
+ assertNotNull( "identity column did not force immediate insert", id );
+ assertEquals( id, myEntity.getId() );
+ s.delete( myEntity );
+ s.getTransaction().commit();
+ s.close();
+ }
+
+ public void testPersistOutsideTransaction() {
+ Session s = openSession();
+
+ // first test save() which should force an immediate insert...
+ MyEntity myEntity1 = new MyEntity( "test-save" );
+ Long id = ( Long ) s.save( myEntity1 );
+ assertNotNull( "identity column did not force immediate insert", id );
+ assertEquals( id, myEntity1.getId() );
+
+ // next test persist() which should cause a delayed insert...
+ long initialInsertCount = sfi().getStatistics().getEntityInsertCount();
+ MyEntity myEntity2 = new MyEntity( "test-persist");
+ s.persist( myEntity2 );
+ assertEquals( "persist on identity column not delayed", initialInsertCount, sfi().getStatistics().getEntityInsertCount() );
+ assertNull( myEntity2.getId() );
+
+ // an explicit flush should cause execution of the delayed insertion
+ s.flush();
+ assertEquals( "delayed persist insert not executed on flush", initialInsertCount + 1, sfi().getStatistics().getEntityInsertCount() );
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ s.delete( myEntity1 );
+ s.delete( myEntity2 );
+ s.getTransaction().commit();
+ s.close();
+ }
+
+ public void testPersistOutsideTransactionCascadedToNonInverseCollection() {
+ long initialInsertCount = sfi().getStatistics().getEntityInsertCount();
+ Session s = openSession();
+ MyEntity myEntity = new MyEntity( "test-persist");
+ myEntity.getNonInverseChildren().add( new MyChild( "test-child-persist-non-inverse" ) );
+ s.persist( myEntity );
+ assertEquals( "persist on identity column not delayed", initialInsertCount, sfi().getStatistics().getEntityInsertCount() );
+ assertNull( myEntity.getId() );
+ s.flush();
+ assertEquals( "delayed persist insert not executed on flush", initialInsertCount + 2, sfi().getStatistics().getEntityInsertCount() );
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ s.createQuery( "delete MyChild" ).executeUpdate();
+ s.createQuery( "delete MyEntity" ).executeUpdate();
+ s.getTransaction().commit();
+ s.close();
+ }
+
+ public void testPersistOutsideTransactionCascadedToInverseCollection() {
+ long initialInsertCount = sfi().getStatistics().getEntityInsertCount();
+ Session s = openSession();
+ MyEntity myEntity2 = new MyEntity( "test-persist-2");
+ MyChild child = new MyChild( "test-child-persist-inverse" );
+ myEntity2.getInverseChildren().add( child );
+ child.setInverseParent( myEntity2 );
+ s.persist( myEntity2 );
+ assertEquals( "persist on identity column not delayed", initialInsertCount, sfi().getStatistics().getEntityInsertCount() );
+ assertNull( myEntity2.getId() );
+ s.flush();
+ assertEquals( "delayed persist insert not executed on flush", initialInsertCount + 2, sfi().getStatistics().getEntityInsertCount() );
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ s.createQuery( "delete MyChild" ).executeUpdate();
+ s.createQuery( "delete MyEntity" ).executeUpdate();
+ s.getTransaction().commit();
+ s.close();
+ }
+
+ public void testPersistOutsideTransactionCascadedToManyToOne() {
+ long initialInsertCount = sfi().getStatistics().getEntityInsertCount();
+ Session s = openSession();
+ MyEntity myEntity = new MyEntity( "test-persist");
+ myEntity.setSibling( new MySibling( "test-persist-sibling-out" ) );
+ s.persist( myEntity );
+ assertEquals( "persist on identity column not delayed", initialInsertCount, sfi().getStatistics().getEntityInsertCount() );
+ assertNull( myEntity.getId() );
+ s.flush();
+ assertEquals( "delayed persist insert not executed on flush", initialInsertCount + 2, sfi().getStatistics().getEntityInsertCount() );
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ s.createQuery( "delete MyEntity" ).executeUpdate();
+ s.createQuery( "delete MySibling" ).executeUpdate();
+ s.getTransaction().commit();
+ s.close();
+ }
+
+ public void testPersistOutsideTransactionCascadedFromManyToOne() {
+ long initialInsertCount = sfi().getStatistics().getEntityInsertCount();
+ Session s = openSession();
+ MyEntity myEntity2 = new MyEntity( "test-persist-2");
+ MySibling sibling = new MySibling( "test-persist-sibling-in" );
+ sibling.setEntity( myEntity2 );
+ s.persist( sibling );
+ assertEquals( "persist on identity column not delayed", initialInsertCount, sfi().getStatistics().getEntityInsertCount() );
+ assertNull( myEntity2.getId() );
+ s.flush();
+ assertEquals( "delayed persist insert not executed on flush", initialInsertCount + 2, sfi().getStatistics().getEntityInsertCount() );
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ s.createQuery( "delete MySibling" ).executeUpdate();
+ s.createQuery( "delete MyEntity" ).executeUpdate();
+ s.getTransaction().commit();
+ s.close();
+ }
+}
Added: trunk/Hibernate3/test/org/hibernate/test/generatedkeys/identity/MyChild.java
===================================================================
--- trunk/Hibernate3/test/org/hibernate/test/generatedkeys/identity/MyChild.java 2006-03-22 13:11:03 UTC (rev 9672)
+++ trunk/Hibernate3/test/org/hibernate/test/generatedkeys/identity/MyChild.java 2006-03-22 14:57:59 UTC (rev 9673)
@@ -0,0 +1,41 @@
+package org.hibernate.test.generatedkeys.identity;
+
+/**
+ * @author Steve Ebersole
+ */
+public class MyChild {
+ private Long id;
+ private String name;
+ private MyEntity inverseParent;
+
+ public MyChild() {
+ }
+
+ public MyChild(String name) {
+ this.name = name;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public MyEntity getInverseParent() {
+ return inverseParent;
+ }
+
+ public void setInverseParent(MyEntity inverseParent) {
+ this.inverseParent = inverseParent;
+ }
+}
Added: trunk/Hibernate3/test/org/hibernate/test/generatedkeys/identity/MyEntity.hbm.xml
===================================================================
--- trunk/Hibernate3/test/org/hibernate/test/generatedkeys/identity/MyEntity.hbm.xml 2006-03-22 13:11:03 UTC (rev 9672)
+++ trunk/Hibernate3/test/org/hibernate/test/generatedkeys/identity/MyEntity.hbm.xml 2006-03-22 14:57:59 UTC (rev 9673)
@@ -0,0 +1,48 @@
+<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<hibernate-mapping package="org.hibernate.test.generatedkeys.identity" default-access="field">
+
+ <class name="MyEntity" table="my_entity">
+ <id name="id">
+ <generator class="identity"/>
+ </id>
+ <property name="name"/>
+
+ <!-- used to test cascades "out" to a many-to-one association -->
+ <many-to-one name="sibling" class="MySibling" cascade="persist, merge"/>
+
+ <!-- used to test cascades "out" to non-inverse collections -->
+ <set name="nonInverseChildren" inverse="false" cascade="persist, merge">
+ <key column="non_inv_parent_id"/>
+ <one-to-many class="MyChild"/>
+ </set>
+
+ <!-- used to test cascades "out" to inverse collections -->
+ <set name="inverseChildren" inverse="true" cascade="persist, merge">
+ <key column="inv_parent_id"/>
+ <one-to-many class="MyChild"/>
+ </set>
+ </class>
+
+
+ <class name="MySibling" table="my_sibling">
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <property name="name"/>
+ <many-to-one name="entity" class="MyEntity" cascade="persist, merge"/>
+ </class>
+
+
+ <class name="MyChild" table="my_child">
+ <id name="id">
+ <generator class="increment"/>
+ </id>
+ <property name="name"/>
+ <many-to-one name="inverseParent" column="inv_parent_id" class="MyEntity"/>
+ </class>
+
+</hibernate-mapping>
\ No newline at end of file
Added: trunk/Hibernate3/test/org/hibernate/test/generatedkeys/identity/MyEntity.java
===================================================================
--- trunk/Hibernate3/test/org/hibernate/test/generatedkeys/identity/MyEntity.java 2006-03-22 13:11:03 UTC (rev 9672)
+++ trunk/Hibernate3/test/org/hibernate/test/generatedkeys/identity/MyEntity.java 2006-03-22 14:57:59 UTC (rev 9673)
@@ -0,0 +1,62 @@
+package org.hibernate.test.generatedkeys.identity;
+
+import java.util.Set;
+import java.util.HashSet;
+
+/**
+ * @author Steve Ebersole
+ */
+public class MyEntity {
+ private Long id;
+ private String name;
+ private MySibling sibling;
+ private Set nonInverseChildren = new HashSet();
+ private Set inverseChildren = new HashSet();
+
+ public MyEntity() {
+ }
+
+ public MyEntity(String name) {
+ this.name = name;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public MySibling getSibling() {
+ return sibling;
+ }
+
+ public void setSibling(MySibling sibling) {
+ this.sibling = sibling;
+ }
+
+ public Set getNonInverseChildren() {
+ return nonInverseChildren;
+ }
+
+ public void setNonInverseChildren(Set nonInverseChildren) {
+ this.nonInverseChildren = nonInverseChildren;
+ }
+
+ public Set getInverseChildren() {
+ return inverseChildren;
+ }
+
+ public void setInverseChildren(Set inverseChildren) {
+ this.inverseChildren = inverseChildren;
+ }
+}
Added: trunk/Hibernate3/test/org/hibernate/test/generatedkeys/identity/MySibling.java
===================================================================
--- trunk/Hibernate3/test/org/hibernate/test/generatedkeys/identity/MySibling.java 2006-03-22 13:11:03 UTC (rev 9672)
+++ trunk/Hibernate3/test/org/hibernate/test/generatedkeys/identity/MySibling.java 2006-03-22 14:57:59 UTC (rev 9673)
@@ -0,0 +1,41 @@
+package org.hibernate.test.generatedkeys.identity;
+
+/**
+ * @author Steve Ebersole
+ */
+public class MySibling {
+ private Long id;
+ private String name;
+ private MyEntity entity;
+
+ public MySibling() {
+ }
+
+ public MySibling(String name) {
+ this.name = name;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public MyEntity getEntity() {
+ return entity;
+ }
+
+ public void setEntity(MyEntity entity) {
+ this.entity = entity;
+ }
+}
Modified: trunk/Hibernate3/test/org/hibernate/test/tm/CMTTest.java
===================================================================
--- trunk/Hibernate3/test/org/hibernate/test/tm/CMTTest.java 2006-03-22 13:11:03 UTC (rev 9672)
+++ trunk/Hibernate3/test/org/hibernate/test/tm/CMTTest.java 2006-03-22 14:57:59 UTC (rev 9673)
@@ -15,6 +15,7 @@
import org.hibernate.Session;
import org.hibernate.ScrollableResults;
import org.hibernate.ConnectionReleaseMode;
+import org.hibernate.dialect.SybaseDialect;
import org.hibernate.transaction.CMTTransactionFactory;
import org.hibernate.util.SerializationHelper;
import org.hibernate.cfg.Configuration;
@@ -184,7 +185,10 @@
}
public void testConcurrentCachedDirtyQueries() throws Exception {
-
+ if ( reportSkip( "dead-lock bug", "concurrent queries", getDialect() instanceof SybaseDialect ) ) {
+ // sybase and sqlserver have serious locking issues here...
+ return;
+ }
DummyTransactionManager.INSTANCE.begin();
Session s = openSession();
Map foo = new HashMap();
|
|
From: <hib...@li...> - 2006-03-22 13:11:10
|
Author: ste...@jb...
Date: 2006-03-22 08:11:03 -0500 (Wed, 22 Mar 2006)
New Revision: 9672
Modified:
branches/Branch_3_1/Hibernate3/doc/reference/build.xml
Log:
activated zh-cn reference doc translation
Modified: branches/Branch_3_1/Hibernate3/doc/reference/build.xml
===================================================================
--- branches/Branch_3_1/Hibernate3/doc/reference/build.xml 2006-03-22 11:00:49 UTC (rev 9671)
+++ branches/Branch_3_1/Hibernate3/doc/reference/build.xml 2006-03-22 13:11:03 UTC (rev 9672)
@@ -41,9 +41,9 @@
<!-- TRANSLATOR: Duplicate this line for your language -->
<antcall target="lang.all"><param name="lang" value="en"/></antcall>
<antcall target="lang.all"><param name="lang" value="fr"/></antcall>
- <antcall target="lang.all"><param name="lang" value="ko"/></antcall>
+ <antcall target="lang.all"><param name="lang" value="ko"/></antcall>
+ <antcall target="lang.all"><param name="lang" value="zh-cn"/></antcall>
<!-- TODO: These translations need updating...
- <antcall target="lang.all"><param name="lang" value="zh-cn"/></antcall>
<antcall target="lang.all"><param name="lang" value="es"/></antcall>
-->
|
|
From: <hib...@li...> - 2006-03-22 11:00:55
|
Author: ami...@jb...
Date: 2006-03-22 06:00:49 -0500 (Wed, 22 Mar 2006)
New Revision: 9671
Modified:
trunk/Hibernate3/src/org/hibernate/cfg/Environment.java
Log:
Changed hibernate.bytecode.use_reflection_optimizer to Flase by default to fix HHH-227
Modified: trunk/Hibernate3/src/org/hibernate/cfg/Environment.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/cfg/Environment.java 2006-03-22 06:06:17 UTC (rev 9670)
+++ trunk/Hibernate3/src/org/hibernate/cfg/Environment.java 2006-03-22 11:00:49 UTC (rev 9671)
@@ -416,7 +416,7 @@
*/
public static final String QUERY_SUBSTITUTIONS = "hibernate.query.substitutions";
/**
- * Auto export/update schema using hbm2ddl tool. Valid values are <tt>update</tt>,
+ * Auto export/update schema using hbm2ddl tool. Valid values are <tt>update</tt>,
* <tt>create</tt>, <tt>create-drop</tt> and <tt>validate</tt>.
*/
public static final String HBM2DDL_AUTO = "hibernate.hbm2ddl.auto";
@@ -443,7 +443,7 @@
* The EntityMode in which set the Session opened from the SessionFactory.
*/
public static final String DEFAULT_ENTITY_MODE = "hibernate.default_entity_mode";
-
+
/**
* The jacc context id of the deployment
*/
@@ -482,7 +482,7 @@
newPropertyName = RENAMED_PROPERTIES.get( propertyName );
if ( newPropertyName != null ) {
log.warn( "Property [" + propertyName + "] has been renamed to [" + newPropertyName + "]; update your properties appropriately" );
- if ( ! props.containsKey( newPropertyName ) ) {
+ if ( ! props.containsKey( newPropertyName ) ) {
propertiesToAdd.put( newPropertyName, props.get( propertyName ) );
}
}
@@ -503,7 +503,8 @@
ISOLATION_LEVELS.put( new Integer(Connection.TRANSACTION_SERIALIZABLE), "SERIALIZABLE" );
GLOBAL_PROPERTIES = new Properties();
- GLOBAL_PROPERTIES.setProperty( USE_REFLECTION_OPTIMIZER, Boolean.TRUE.toString() );
+ //Set USE_REFLECTION_OPTIMIZER to false to fix HHH-227
+ GLOBAL_PROPERTIES.setProperty( USE_REFLECTION_OPTIMIZER, Boolean.FALSE.toString() );
try {
InputStream stream = ConfigHelper.getResourceAsStream("/hibernate.properties");
|
|
From: <pt...@12...> - 2006-03-22 03:14:29
|
aGliZXJuYXRlLWNvbW1pdHOjrMT6usOjoQ0KDQoJDQoNCqGhoaGhoaGhoaGhoaGhoaHWwg0KwPGj oQ0KIAkJCQkNCg0KoaGhoaGhoaGhoaGhoaGhoXB0bWFuDQqhoaGhoaGhoaGhoaGhoaGhcHRtYW5A MTI2LmNvbQ0KoaGhoaGhoaGhoaGhoaGhoaGhoaEyMDA2LTAzLTIyDQo= |
|
From: <hib...@li...> - 2006-03-21 14:14:30
|
Author: ste...@jb... Date: 2006-03-21 09:14:21 -0500 (Tue, 21 Mar 2006) New Revision: 9669 Modified: trunk/Hibernate3/test/org/hibernate/test/ejb3/lock/RepeatableReadTest.java Log: fix test Modified: trunk/Hibernate3/test/org/hibernate/test/ejb3/lock/RepeatableReadTest.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/ejb3/lock/RepeatableReadTest.java 2006-03-20 20:03:44 UTC (rev 9668) +++ trunk/Hibernate3/test/org/hibernate/test/ejb3/lock/RepeatableReadTest.java 2006-03-21 14:14:21 UTC (rev 9669) @@ -84,8 +84,7 @@ assertEquals( "encountered non-repeatable read", initialVersion, item2.getVersion() ); // clean up - s1.refresh( item ); - s1.delete( item ); + s1.createQuery( "delete Item" ).executeUpdate(); t1.commit(); s1.close(); } @@ -138,8 +137,7 @@ } // clean up - s1.refresh( item ); - s1.delete( item ); + s1.createQuery( "delete Item" ).executeUpdate(); t1.commit(); s1.close(); } |
|
From: <hib...@li...> - 2006-03-20 20:03:49
|
Author: ste...@jb... Date: 2006-03-20 15:03:44 -0500 (Mon, 20 Mar 2006) New Revision: 9668 Added: tags/v313/Hibernate3/ Log: re-tagging 3.1.3 Copied: tags/v313/Hibernate3 (from rev 9667, branches/Branch_3_1/Hibernate3) |
|
From: <hib...@li...> - 2006-03-20 20:02:43
|
Author: ste...@jb... Date: 2006-03-20 15:02:38 -0500 (Mon, 20 Mar 2006) New Revision: 9667 Removed: tags/v313/Hibernate3/ Log: Removed file/folder |
|
From: <hib...@li...> - 2006-03-20 19:30:04
|
Author: bi...@jb...
Date: 2006-03-20 14:29:27 -0500 (Mon, 20 Mar 2006)
New Revision: 9666
Modified:
trunk/HibernateExt/ejb/lib/hibernate-annotations.jar
trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/packaging/PersistenceXmlLoader.java
Log:
optional schema validation. If no schema, don't validate
Modified: trunk/HibernateExt/ejb/lib/hibernate-annotations.jar
===================================================================
(Binary files differ)
Modified: trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/packaging/PersistenceXmlLoader.java
===================================================================
--- trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/packaging/PersistenceXmlLoader.java 2006-03-20 19:27:29 UTC (rev 9665)
+++ trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/packaging/PersistenceXmlLoader.java 2006-03-20 19:29:27 UTC (rev 9666)
@@ -17,6 +17,7 @@
import org.apache.commons.logging.LogFactory;
import org.hibernate.ejb.HibernatePersistence;
import org.hibernate.util.StringHelper;
+import org.hibernate.cfg.EJB3DTDEntityResolver;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
@@ -51,7 +52,7 @@
try {
//otherwise Xerces fails in validation
docBuilderFactory.setAttribute( "http://apache.org/xml/features/validation/schema", true);
- }
+ }
catch (IllegalArgumentException e) {
docBuilderFactory.setValidating( false );
docBuilderFactory.setNamespaceAware( false );
@@ -59,9 +60,9 @@
InputSource source = new InputSource( is );
DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
docBuilder.setEntityResolver( resolver );
- docBuilder.setErrorHandler( new ErrorLogger("XML InputStream", errors) );
+ docBuilder.setErrorHandler( new ErrorLogger("XML InputStream", errors, resolver) );
Document doc = docBuilder.parse( source );
- if ( errors.size() != 0 ) {
+ if ( errors.size() != 0 ) {
throw new PersistenceException( "invalid persistence.xml", (Throwable) errors.get( 0 ) );
}
return doc;
@@ -184,16 +185,23 @@
public static class ErrorLogger implements ErrorHandler {
private String file;
private List errors;
- ErrorLogger(String file, List errors) {
+ private EntityResolver resolver;
+ ErrorLogger(String file, List errors, EntityResolver resolver) {
this.file=file;
this.errors = errors;
- }
+ this.resolver = resolver;
+ }
public void error(SAXParseException error) {
- log.error( "Error parsing XML: " + file + '(' + error.getLineNumber() + ") " + error.getMessage() );
+ if (resolver instanceof EJB3DTDEntityResolver)
+ {
+ if (((EJB3DTDEntityResolver)resolver).isResolved() == false) return;
+ }
+ log.error( "Error parsing XML: " + file + '(' + error.getLineNumber() + ") " + error.getMessage() );
errors.add(error);
}
public void fatalError(SAXParseException error) {
- error(error);
+ log.error( "Error parsing XML: " + file + '(' + error.getLineNumber() + ") " + error.getMessage() );
+ errors.add(error);
}
public void warning(SAXParseException warn) {
log.warn( "Warning parsing XML: " + file + '(' + warn.getLineNumber() + ") " + warn.getMessage() );
|
|
From: <hib...@li...> - 2006-03-20 19:28:10
|
Author: bi...@jb...
Date: 2006-03-20 14:27:29 -0500 (Mon, 20 Mar 2006)
New Revision: 9665
Modified:
trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/AnnotationConfiguration.java
trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/EJB3DTDEntityResolver.java
Log:
optional schema validation. If no schema, don't validate
Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/AnnotationConfiguration.java
===================================================================
--- trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/AnnotationConfiguration.java 2006-03-20 15:10:41 UTC (rev 9664)
+++ trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/AnnotationConfiguration.java 2006-03-20 19:27:29 UTC (rev 9665)
@@ -198,7 +198,7 @@
annotatedClassEntities = new HashMap<String, XClass>();
hbmDocuments = new ArrayList<Document>();
namingStrategy = EJB3NamingStrategy.INSTANCE;
- setEntityResolver( EJB3DTDEntityResolver.INSTANCE );
+ setEntityResolver( new EJB3DTDEntityResolver() );
}
@Override
Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/EJB3DTDEntityResolver.java
===================================================================
--- trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/EJB3DTDEntityResolver.java 2006-03-20 15:10:41 UTC (rev 9664)
+++ trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/EJB3DTDEntityResolver.java 2006-03-20 19:27:29 UTC (rev 9665)
@@ -17,7 +17,14 @@
private static final Log log = LogFactory.getLog( EJB3DTDEntityResolver.class );
- public InputSource resolveEntity(String publicId, String systemId) {
+ boolean resolved = false;
+
+ public boolean isResolved()
+ {
+ return resolved;
+ }
+
+ public InputSource resolveEntity(String publicId, String systemId) {
InputSource is = super.resolveEntity( publicId, systemId );
if (is == null) {
if ( systemId != null ) {
@@ -33,7 +40,8 @@
InputSource source = new InputSource( dtdStream );
source.setPublicId( publicId );
source.setSystemId( systemId );
- return source;
+ resolved = false;
+ return source;
}
}
else if ( systemId.endsWith( "persistence_1_0.xsd" ) ) {
@@ -48,13 +56,15 @@
InputSource source = new InputSource( dtdStream );
source.setPublicId( publicId );
source.setSystemId( systemId );
- return source;
+ resolved = true;
+ return source;
}
}
}
}
else {
- return is;
+ resolved = true;
+ return is;
}
//use the default behavior
return null;
|
|
From: <hib...@li...> - 2006-03-20 14:46:05
|
Author: ste...@jb...
Date: 2006-03-20 09:45:56 -0500 (Mon, 20 Mar 2006)
New Revision: 9663
Modified:
branches/Branch_3_1/Hibernate3/build.xml
branches/Branch_3_1/Hibernate3/changelog.txt
branches/Branch_3_1/Hibernate3/doc/reference/en/master.xml
branches/Branch_3_1/Hibernate3/readme.txt
branches/Branch_3_1/Hibernate3/src/org/hibernate/cfg/Environment.java
Log:
prep 3.1.3
Modified: branches/Branch_3_1/Hibernate3/build.xml
===================================================================
--- branches/Branch_3_1/Hibernate3/build.xml 2006-03-20 14:38:01 UTC (rev 9662)
+++ branches/Branch_3_1/Hibernate3/build.xml 2006-03-20 14:45:56 UTC (rev 9663)
@@ -18,7 +18,7 @@
<property name="name2" value="hibernate3"/>
<property name="version.major" value="3"/>
<property name="version.minor" value="1"/>
- <property name="version.patchlevel" value="2"/>
+ <property name="version.patchlevel" value="3"/>
<property name="version.sansPatchLevel" value="${version.major}.${version.minor}"/>
<property name="version.full" value="${version.sansPatchLevel}.${version.patchlevel}"/>
<property name="fullname" value="${name}-${version.full}"/>
Modified: branches/Branch_3_1/Hibernate3/changelog.txt
===================================================================
--- branches/Branch_3_1/Hibernate3/changelog.txt 2006-03-20 14:38:01 UTC (rev 9662)
+++ branches/Branch_3_1/Hibernate3/changelog.txt 2006-03-20 14:45:56 UTC (rev 9663)
@@ -5,7 +5,39 @@
refer to the particular case on JIRA using the issue tracking number to learn
more about each case.
+Changes in version 3.1.3 (2006.03.20)
+-------------------------------------------
+** Bug
+ * [HHH-535] - properties element causes exception in interface/abstract class
+ * [HHH-1236] - Remove static reference to classloader, to avoid memory leak at webapp reload
+ * [HHH-1248] - explicit joins to collections in subquery result in join conditions being dropped from sql
+ * [HHH-1287] - Problem with WAS ExtendedJTATransaction not available when using MDB
+ * [HHH-1325] - ArrayOutOfBounds expected in DatabaseMetadata.isTable when specifing schema
+ * [HHH-1419] - Update + Exists doesn't seem to work
+ * [HHH-1433] - many-to-many with additional 'with' join clause generates bad sql
+ * [HHH-1435] - many-to-one lazy seems to be broken in 3.1.x
+ * [HHH-1445] - SchemaUpdate closes shared ConnectionProvider
+ * [HHH-1453] - Broken exception handling in NullableType
+ * [HHH-1464] - QueryException from Query.getReturnAliases when query uses "fetch"
+ * [HHH-1486] - Concurrent access issues with both SoftLimitMRUCache and SimpleMRUCache
+ * [HHH-1489] - mapped composite is is always assumed as transient
+ * [HHH-1508] - Session.createQuery() should not flush the session
+ * [HHH-1531] - NPE with many-to-many and property-ref
+ * [HHH-1546] - generated version properties fail with multiple actions per flush
+
+** Improvement
+ * [HHH-1430] - More complete TransactionManager in GlassFish (SunOne 9) and 8
+ * [HHH-1516] - support DataDirect standard jdbc stored procedures
+ * [HHH-1520] - with clause with implied joins within an explicit join
+ * [HHH-1526] - Improved DTDEntityResolver
+ * [HHH-1540] - Better Error Feedback In CollectionEntry.postFlush(PersistentCollection)
+ * [HHH-1555] - ConnectionReleaseMode.AFTER_STATEMENT and flushes
+
+** New Feature
+ * [HHH-1251] - Avoid replicating the clearing of TreeCache on SessionFactory..close()
+
+
Changes in version 3.1.2 (01.27.2006)
-------------------------------------------
Modified: branches/Branch_3_1/Hibernate3/doc/reference/en/master.xml
===================================================================
--- branches/Branch_3_1/Hibernate3/doc/reference/en/master.xml 2006-03-20 14:38:01 UTC (rev 9662)
+++ branches/Branch_3_1/Hibernate3/doc/reference/en/master.xml 2006-03-20 14:45:56 UTC (rev 9663)
@@ -33,7 +33,7 @@
<bookinfo>
<title>HIBERNATE - Relational Persistence for Idiomatic Java</title>
<subtitle>Hibernate Reference Documentation</subtitle>
- <releaseinfo>3.1.2</releaseinfo>
+ <releaseinfo>3.1.3</releaseinfo>
</bookinfo>
<toc/>
Modified: branches/Branch_3_1/Hibernate3/readme.txt
===================================================================
--- branches/Branch_3_1/Hibernate3/readme.txt 2006-03-20 14:38:01 UTC (rev 9662)
+++ branches/Branch_3_1/Hibernate3/readme.txt 2006-03-20 14:45:56 UTC (rev 9663)
@@ -1,6 +1,6 @@
Hibernate - Relational Persistence for Idiomatic Java
=====================================================
-version 3.1.2, Jan 27, 2006
+version 3.1.3, March 20, 2006
Instructions
------------
Modified: branches/Branch_3_1/Hibernate3/src/org/hibernate/cfg/Environment.java
===================================================================
--- branches/Branch_3_1/Hibernate3/src/org/hibernate/cfg/Environment.java 2006-03-20 14:38:01 UTC (rev 9662)
+++ branches/Branch_3_1/Hibernate3/src/org/hibernate/cfg/Environment.java 2006-03-20 14:45:56 UTC (rev 9663)
@@ -152,7 +152,7 @@
*/
public final class Environment {
- public static final String VERSION = "3.1.2";
+ public static final String VERSION = "3.1.3";
/**
* <tt>ConnectionProvider</tt> implementor to use when obtaining connections
|
|
From: <hib...@li...> - 2006-03-20 14:38:17
|
Author: ste...@jb... Date: 2006-03-20 09:38:01 -0500 (Mon, 20 Mar 2006) New Revision: 9662 Added: tags/v313/Hibernate3/ Log: tagging 3.1.3 Copied: tags/v313/Hibernate3 (from rev 9661, trunk/Hibernate3) |
|
From: <hib...@li...> - 2006-03-20 14:35:49
|
Author: ste...@jb... Date: 2006-03-20 09:35:41 -0500 (Mon, 20 Mar 2006) New Revision: 9661 Added: tags/v313/ Log: created 3.1.3 tag folder |