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 |