From: <hib...@li...> - 2006-03-27 16:47:18
|
Author: ste...@jb... Date: 2006-03-27 11:47:06 -0500 (Mon, 27 Mar 2006) New Revision: 9686 Added: trunk/Hibernate3/src/org/hibernate/id/SequenceIdentityGenerator.java trunk/Hibernate3/src/org/hibernate/util/NamedGeneratedKeysHelper.java trunk/Hibernate3/test/org/hibernate/test/generatedkeys/select/ trunk/Hibernate3/test/org/hibernate/test/generatedkeys/select/MyEntity.hbm.xml trunk/Hibernate3/test/org/hibernate/test/generatedkeys/select/SelectGeneratorTest.java trunk/Hibernate3/test/org/hibernate/test/generatedkeys/seqidentity/ trunk/Hibernate3/test/org/hibernate/test/generatedkeys/seqidentity/MyEntity.hbm.xml trunk/Hibernate3/test/org/hibernate/test/generatedkeys/seqidentity/MyEntity.java trunk/Hibernate3/test/org/hibernate/test/generatedkeys/seqidentity/SequenceIdentityTest.java Removed: trunk/Hibernate3/test/org/hibernate/test/generatedkeys/oracle/ trunk/Hibernate3/test/org/hibernate/test/generatedkeys/select/MyEntity.hbm.xml trunk/Hibernate3/test/org/hibernate/test/generatedkeys/select/OracleGeneratedKeysTest.java Modified: trunk/Hibernate3/src/org/hibernate/id/IdentifierGeneratorFactory.java trunk/Hibernate3/src/org/hibernate/id/SequenceGenerator.java trunk/Hibernate3/src/org/hibernate/id/insert/AbstractReturningDelegate.java trunk/Hibernate3/src/org/hibernate/jdbc/AbstractBatcher.java trunk/Hibernate3/src/org/hibernate/jdbc/Batcher.java trunk/Hibernate3/test/org/hibernate/test/AllTests.java trunk/Hibernate3/test/org/hibernate/test/generatedkeys/select/MyEntity.java Log: HHH-1179 : sequence-identity (for Oracle) Modified: trunk/Hibernate3/src/org/hibernate/id/IdentifierGeneratorFactory.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/id/IdentifierGeneratorFactory.java 2006-03-27 15:48:23 UTC (rev 9685) +++ trunk/Hibernate3/src/org/hibernate/id/IdentifierGeneratorFactory.java 2006-03-27 16:47:06 UTC (rev 9686) @@ -83,6 +83,7 @@ GENERATORS.put("foreign", ForeignGenerator.class); GENERATORS.put("guid", GUIDGenerator.class); GENERATORS.put("uuid.hex", UUIDHexGenerator.class); //uuid.hex is deprecated + GENERATORS.put("sequence-identity", SequenceIdentityGenerator.class); } public static IdentifierGenerator create(String strategy, Type type, Properties params, Dialect dialect) Modified: trunk/Hibernate3/src/org/hibernate/id/SequenceGenerator.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/id/SequenceGenerator.java 2006-03-27 15:48:23 UTC (rev 9685) +++ trunk/Hibernate3/src/org/hibernate/id/SequenceGenerator.java 2006-03-27 16:47:06 UTC (rev 9686) @@ -105,7 +105,9 @@ public String[] sqlCreateStrings(Dialect dialect) throws HibernateException { String[] ddl = dialect.getCreateSequenceStrings(sequenceName); - if ( parameters!=null ) ddl[ddl.length-1] += ' ' + parameters; + if ( parameters != null ) { + ddl[ddl.length - 1] += ' ' + parameters; + } return ddl; } @@ -117,4 +119,8 @@ return sequenceName; } + public String getSequenceName() { + return sequenceName; + } + } Added: trunk/Hibernate3/src/org/hibernate/id/SequenceIdentityGenerator.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/id/SequenceIdentityGenerator.java 2006-03-27 15:48:23 UTC (rev 9685) +++ trunk/Hibernate3/src/org/hibernate/id/SequenceIdentityGenerator.java 2006-03-27 16:47:06 UTC (rev 9686) @@ -0,0 +1,100 @@ +package org.hibernate.id; + +import org.hibernate.id.insert.InsertGeneratedIdentifierDelegate; +import org.hibernate.id.insert.AbstractReturningDelegate; +import org.hibernate.id.insert.IdentifierGeneratingInsert; +import org.hibernate.dialect.Dialect; +import org.hibernate.HibernateException; +import org.hibernate.MappingException; +import org.hibernate.sql.Insert; +import org.hibernate.util.NamedGeneratedKeysHelper; +import org.hibernate.type.Type; +import org.hibernate.engine.SessionImplementor; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.io.Serializable; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.Properties; + +/** + * A generator which combines sequence generation with immediate retrieval + * through JDBC3 {@link java.sql.Connection#prepareStatement(String, String[]) getGeneratedKeys}. + * In this respect it works much like ANSI-SQL IDENTITY generation. + * <p/> + * This generator only known to work with newer Oracle drivers compiled for + * JDK 1.4 (JDBC3). + * <p/> + * Note: Due to a bug in Oracle drivers, sql comments on these insert statements + * are completely disabled. + * + * @author Steve Ebersole + */ +public class SequenceIdentityGenerator extends SequenceGenerator + implements PostInsertIdentifierGenerator { + + private static final Log log = LogFactory.getLog( SequenceIdentityGenerator.class ); + + public Serializable generate(SessionImplementor s, Object obj) { + return IdentifierGeneratorFactory.POST_INSERT_INDICATOR; + } + + public InsertGeneratedIdentifierDelegate getInsertGeneratedIdentifierDelegate( + PostInsertIdentityPersister persister, + Dialect dialect, + boolean isGetGeneratedKeysEnabled) throws HibernateException { + return new Delegate( persister, dialect, getSequenceName() ); + } + + public void configure(Type type, Properties params, Dialect dialect) throws MappingException { + super.configure( type, params, dialect ); + } + + public static class Delegate extends AbstractReturningDelegate { + private final Dialect dialect; + private final String sequenceNextValFragment; + private final String[] keyColumns; + + public Delegate(PostInsertIdentityPersister persister, Dialect dialect, String sequenceName) { + super( persister ); + this.dialect = dialect; + this.sequenceNextValFragment = dialect.getSelectSequenceNextValString( sequenceName ); + this.keyColumns = getPersister().getRootTableKeyColumnNames(); + if ( keyColumns.length > 1 ) { + throw new HibernateException( "sequence-identity generator cannot be used with with multi-column keys" ); + } + } + + public IdentifierGeneratingInsert prepareIdentifierGeneratingInsert() { + NoCommentsInsert insert = new NoCommentsInsert( dialect ); + insert.addColumn( getPersister().getRootTableKeyColumnNames()[0], sequenceNextValFragment ); + return insert; + } + + protected PreparedStatement prepare(String insertSQL, SessionImplementor session) throws SQLException { + return session.getBatcher().prepareStatement( insertSQL, keyColumns ); + } + + protected Serializable executeAndExtract(PreparedStatement insert) throws SQLException { + insert.executeUpdate(); + return IdentifierGeneratorFactory.getGeneratedIdentity( + NamedGeneratedKeysHelper.getGeneratedKey( insert ), + getPersister().getIdentifierType() + ); + } + } + + public static class NoCommentsInsert extends IdentifierGeneratingInsert { + public NoCommentsInsert(Dialect dialect) { + super( dialect ); + } + + public Insert setComment(String comment) { + // don't allow comments on these insert statements as comments totally + // blow up the Oracle getGeneratedKeys "support" :( + log.info( "disallowing insert statement comment for select-identity due to Oracle driver bug" ); + return this; + } + } +} Modified: trunk/Hibernate3/src/org/hibernate/id/insert/AbstractReturningDelegate.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/id/insert/AbstractReturningDelegate.java 2006-03-27 15:48:23 UTC (rev 9685) +++ trunk/Hibernate3/src/org/hibernate/id/insert/AbstractReturningDelegate.java 2006-03-27 16:47:06 UTC (rev 9686) @@ -33,7 +33,7 @@ return executeAndExtract( insert ); } finally { - session.getBatcher().closeStatement( insert ); + releaseStatement( insert, session ); } } catch ( SQLException sqle ) { @@ -46,7 +46,15 @@ } } + protected PostInsertIdentityPersister getPersister() { + return persister; + } + protected abstract PreparedStatement prepare(String insertSQL, SessionImplementor session) throws SQLException; protected abstract Serializable executeAndExtract(PreparedStatement insert) throws SQLException; + + protected void releaseStatement(PreparedStatement insert, SessionImplementor session) throws SQLException { + session.getBatcher().closeStatement( insert ); + } } Modified: trunk/Hibernate3/src/org/hibernate/jdbc/AbstractBatcher.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/jdbc/AbstractBatcher.java 2006-03-27 15:48:23 UTC (rev 9685) +++ trunk/Hibernate3/src/org/hibernate/jdbc/AbstractBatcher.java 2006-03-27 16:47:06 UTC (rev 9686) @@ -22,6 +22,7 @@ import org.hibernate.pretty.Formatter; import org.hibernate.util.GetGeneratedKeysHelper; import org.hibernate.util.JDBCExceptionReporter; +import org.hibernate.util.NamedGeneratedKeysHelper; /** * Manages prepared statements and batching. @@ -51,7 +52,7 @@ private boolean releasing = false; private final Interceptor interceptor; - + private long transactionTimeout = -1; boolean isTransactionTimeoutSet; @@ -65,23 +66,23 @@ isTransactionTimeoutSet = true; transactionTimeout = System.currentTimeMillis() / 1000 + seconds; } - + public void unsetTransactionTimeout() { isTransactionTimeoutSet = false; } - + protected PreparedStatement getStatement() { return batchUpdate; } - public CallableStatement prepareCallableStatement(String sql) + public CallableStatement prepareCallableStatement(String sql) throws SQLException, HibernateException { executeBatch(); logOpenPreparedStatement(); return getCallableStatement( connectionManager.getConnection(), sql, false); } - public PreparedStatement prepareStatement(String sql) + public PreparedStatement prepareStatement(String sql) throws SQLException, HibernateException { return prepareStatement( sql, false ); } @@ -96,10 +97,26 @@ false, getGeneratedKeys, null, + null, false ); } + public PreparedStatement prepareStatement(String sql, String[] columnNames) + throws SQLException, HibernateException { + executeBatch(); + logOpenPreparedStatement(); + return getPreparedStatement( + connectionManager.getConnection(), + sql, + false, + false, + columnNames, + null, + false + ); + } + public PreparedStatement prepareSelectStatement(String sql) throws SQLException, HibernateException { logOpenPreparedStatement(); @@ -109,6 +126,7 @@ false, false, null, + null, false ); } @@ -140,6 +158,7 @@ sql, scrollable, false, + null, scrollMode, true ); @@ -175,7 +194,7 @@ resultSetsToClose.add(rs); logOpenResults(); return rs; - + } public void closeQueryStatement(PreparedStatement ps, ResultSet rs) throws SQLException { statementsToClose.remove(ps); @@ -194,7 +213,7 @@ public PreparedStatement prepareBatchStatement(String sql) throws SQLException, HibernateException { sql = getSQL( sql ); - + if ( !sql.equals(batchUpdateSQL) ) { batchUpdate=prepareStatement(sql); // calls executeBatch() batchUpdateSQL=sql; @@ -263,7 +282,7 @@ } if ( lastQuery==ps ) lastQuery = null; - + } /** @@ -315,11 +334,11 @@ } protected abstract void doExecuteBatch(PreparedStatement ps) throws SQLException, HibernateException; - + private String preparedStatementCountsToString() { return - " (open PreparedStatements: " + - openPreparedStatementCount + + " (open PreparedStatements: " + + openPreparedStatementCount + ", globally: " + globalOpenPreparedStatementCount + ")"; @@ -327,8 +346,8 @@ private String resultSetCountsToString() { return - " (open ResultSets: " + - openResultSetCount + + " (open ResultSets: " + + openResultSetCount + ", globally: " + globalOpenResultSetCount + ")"; @@ -368,7 +387,7 @@ protected SessionFactoryImplementor getFactory() { return factory; } - + private void log(String sql) { if ( SQL_LOG.isDebugEnabled() ) { SQL_LOG.debug( format(sql) ); @@ -377,7 +396,7 @@ System.out.println( "Hibernate: " + format(sql) ); } } - + private String format(String sql) { if ( factory.getSettings().isFormatSqlEnabled() ) { return new Formatter(sql).format(); @@ -388,16 +407,17 @@ } private PreparedStatement getPreparedStatement( - final Connection conn, - final String sql, - final boolean scrollable, - final ScrollMode scrollMode) + final Connection conn, + final String sql, + final boolean scrollable, + final ScrollMode scrollMode) throws SQLException { return getPreparedStatement( conn, sql, scrollable, false, + null, scrollMode, false ); @@ -405,15 +425,15 @@ private CallableStatement getCallableStatement( final Connection conn, - String sql, - boolean scrollable) throws SQLException { + String sql, + boolean scrollable) throws SQLException { if ( scrollable && !factory.getSettings().isScrollableResultSetsEnabled() ) { throw new AssertionFailure("scrollable result sets are not enabled"); } sql = getSQL( sql ); log( sql ); - + log.trace("preparing callable statement"); if ( scrollable ) { return conn.prepareCall( @@ -436,12 +456,13 @@ } private PreparedStatement getPreparedStatement( - final Connection conn, - String sql, - boolean scrollable, - final boolean useGetGeneratedKeys, - final ScrollMode scrollMode, - final boolean callable) throws SQLException { + final Connection conn, + String sql, + boolean scrollable, + final boolean useGetGeneratedKeys, + final String[] namedGeneratedKeys, + final ScrollMode scrollMode, + final boolean callable) throws SQLException { if ( scrollable && !factory.getSettings().isScrollableResultSetsEnabled() ) { throw new AssertionFailure("scrollable result sets are not enabled"); } @@ -457,7 +478,7 @@ 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 ); } @@ -465,21 +486,24 @@ else if ( useGetGeneratedKeys ) { result = GetGeneratedKeysHelper.prepareStatement( conn, sql ); } + else if ( namedGeneratedKeys != null ) { + result = NamedGeneratedKeysHelper.prepareStatement( conn, sql, namedGeneratedKeys ); + } else { if ( callable ) { result = conn.prepareCall( sql ); - } + } else { result = conn.prepareStatement( sql ); } } - + setTimeout( result ); - + if ( factory.getStatistics().isStatisticsEnabled() ) { factory.getStatisticsImplementor().prepareStatement(); } - + return result; } @@ -528,18 +552,18 @@ catch (SQLException sqle) { throw JDBCExceptionHelper.convert( factory.getSQLExceptionConverter(), - sqle, - "Cannot open connection" + sqle, + "Cannot open connection" ); } } public void closeConnection(Connection conn) throws HibernateException { if ( log.isDebugEnabled() ) { - log.debug( - "closing JDBC connection" + - preparedStatementCountsToString() + - resultSetCountsToString() + log.debug( + "closing JDBC connection" + + preparedStatementCountsToString() + + resultSetCountsToString() ); } @@ -552,8 +576,8 @@ catch (SQLException sqle) { throw JDBCExceptionHelper.convert( factory.getSQLExceptionConverter(), - sqle, - "Cannot close connection" + sqle, + "Cannot close connection" ); } } @@ -565,8 +589,8 @@ catch (SQLException sqle) { throw JDBCExceptionHelper.convert( factory.getSQLExceptionConverter(), - sqle, - "Cannot cancel query" + sqle, + "Cannot cancel query" ); } } Modified: trunk/Hibernate3/src/org/hibernate/jdbc/Batcher.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/jdbc/Batcher.java 2006-03-27 15:48:23 UTC (rev 9685) +++ trunk/Hibernate3/src/org/hibernate/jdbc/Batcher.java 2006-03-27 16:47:06 UTC (rev 9686) @@ -47,19 +47,32 @@ public PreparedStatement prepareSelectStatement(String sql) throws SQLException, HibernateException; /** - * Get a non-batchable prepared statement to use for inserting / deleting / updating. - * Must be explicitly released by <tt>closeStatement()</tt> + * Get a non-batchable prepared statement to use for inserting / deleting / updating, + * using JDBC3 getGeneratedKeys ({@link Connection#prepareStatement(String, int)}). + * <p/> + * Must be explicitly released by {@link #closeStatement} after use. */ 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> + * using JDBC3 getGeneratedKeys ({@link Connection#prepareStatement(String, String[])}). + * <p/> + * Must be explicitly released by {@link #closeStatement} after use. */ + public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException, HibernateException; + + /** + * Get a non-batchable prepared statement to use for inserting / deleting / updating. + * <p/> + * Must be explicitly released by {@link #closeStatement} after use. + */ public PreparedStatement prepareStatement(String sql) throws SQLException, HibernateException; /** * Get a non-batchable callable statement to use for inserting / deleting / updating. - * Must be explicitly released by <tt>closeStatement()</tt> + * <p/> + * Must be explicitly released by {@link #closeStatement} after use. */ public CallableStatement prepareCallableStatement(String sql) throws SQLException, HibernateException; @@ -67,6 +80,7 @@ * Close a prepared or callable statement opened using <tt>prepareStatement()</tt> or <tt>prepareCallableStatement()</tt> */ public void closeStatement(PreparedStatement ps) throws SQLException; + /** * Get a batchable prepared statement to use for inserting / deleting / updating * (might be called many times before a single call to <tt>executeBatch()</tt>). @@ -147,8 +161,3 @@ public void unsetTransactionTimeout(); } - - - - - Added: trunk/Hibernate3/src/org/hibernate/util/NamedGeneratedKeysHelper.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/util/NamedGeneratedKeysHelper.java 2006-03-27 15:48:23 UTC (rev 9685) +++ trunk/Hibernate3/src/org/hibernate/util/NamedGeneratedKeysHelper.java 2006-03-27 16:47:06 UTC (rev 9686) @@ -0,0 +1,79 @@ +package org.hibernate.util; + +import org.hibernate.AssertionFailure; + +import java.lang.reflect.Method; +import java.lang.reflect.InvocationTargetException; +import java.sql.Connection; +import java.sql.Statement; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.sql.ResultSet; + +/** + * @author Steve Ebersole + */ +public class NamedGeneratedKeysHelper { + private NamedGeneratedKeysHelper() { + } + + private static final Method PREPARE_STATEMENT_METHOD; + private static final Method GET_GENERATED_KEYS_METHOD; + + static { + try { + PREPARE_STATEMENT_METHOD = Connection.class.getMethod( + "prepareStatement", + new Class[] { String.class, String[].class } + ); + GET_GENERATED_KEYS_METHOD = Statement.class.getDeclaredMethod( + "getGeneratedKeys", + null + ); + } + catch ( Exception e ) { + throw new AssertionFailure( "could not initialize getGeneratedKeys() support", e ); + } + } + + public static PreparedStatement prepareStatement(Connection conn, String sql, String[] columnNames) throws SQLException { + Object[] args = new Object[] { sql, columnNames } ; + try { + return ( PreparedStatement ) PREPARE_STATEMENT_METHOD.invoke( conn, args ); + } + catch ( InvocationTargetException ite ) { + if ( ite.getTargetException() instanceof SQLException ) { + throw ( SQLException ) ite.getTargetException(); + } + else if ( ite.getTargetException() instanceof RuntimeException ) { + throw ( RuntimeException ) ite.getTargetException(); + } + else { + throw new AssertionFailure( "InvocationTargetException preparing statement capable of returning generated keys (JDBC3)", ite ); + } + } + catch ( IllegalAccessException iae ) { + throw new AssertionFailure( "IllegalAccessException preparing statement capable of returning generated keys (JDBC3)", iae ); + } + } + + public static ResultSet getGeneratedKey(PreparedStatement ps) throws SQLException { + try { + return ( ResultSet ) GET_GENERATED_KEYS_METHOD.invoke( ps, null ); + } + catch ( InvocationTargetException ite ) { + if ( ite.getTargetException() instanceof SQLException ) { + throw ( SQLException ) ite.getTargetException(); + } + else if ( ite.getTargetException() instanceof RuntimeException ) { + throw ( RuntimeException ) ite.getTargetException(); + } + else { + throw new AssertionFailure( "InvocationTargetException extracting generated keys (JDBC3)", ite ); + } + } + catch ( IllegalAccessException iae ) { + throw new AssertionFailure( "IllegalAccessException extracting generated keys (JDBC3)", iae ); + } + } +} Modified: trunk/Hibernate3/test/org/hibernate/test/AllTests.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/AllTests.java 2006-03-27 15:48:23 UTC (rev 9685) +++ trunk/Hibernate3/test/org/hibernate/test/AllTests.java 2006-03-27 16:47:06 UTC (rev 9686) @@ -38,7 +38,8 @@ import org.hibernate.test.generated.TimestampGeneratedValuesWithCachingTest; import org.hibernate.test.generated.TriggerGeneratedValuesWithCachingTest; import org.hibernate.test.generated.TriggerGeneratedValuesWithoutCachingTest; -import org.hibernate.test.generatedkeys.oracle.OracleGeneratedKeysTest; +import org.hibernate.test.generatedkeys.select.SelectGeneratorTest; +import org.hibernate.test.generatedkeys.seqidentity.SequenceIdentityTest; import org.hibernate.test.hql.HQLSuite; import org.hibernate.test.id.MultipleHiLoPerTableGeneratorTest; import org.hibernate.test.idbag.IdBagTest; @@ -286,7 +287,8 @@ suite.addTest( TimestampGeneratedValuesWithCachingTest.suite() ); suite.addTest( TriggerGeneratedValuesWithCachingTest.suite() ); suite.addTest( TriggerGeneratedValuesWithoutCachingTest.suite() ); - suite.addTest( OracleGeneratedKeysTest.suite() ); + suite.addTest( SelectGeneratorTest.suite() ); + suite.addTest( SequenceIdentityTest.suite() ); suite.addTest( InterceptorDynamicEntityTest.suite() ); suite.addTest( TuplizerDynamicEntityTest.suite() ); suite.addTest( org.hibernate.test.bytecode.cglib.ReflectionOptimizerTest.suite() ); Copied: trunk/Hibernate3/test/org/hibernate/test/generatedkeys/select (from rev 9531, trunk/Hibernate3/test/org/hibernate/test/generatedkeys/oracle) Deleted: trunk/Hibernate3/test/org/hibernate/test/generatedkeys/select/MyEntity.hbm.xml =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/generatedkeys/oracle/MyEntity.hbm.xml 2006-03-02 03:14:31 UTC (rev 9531) +++ trunk/Hibernate3/test/org/hibernate/test/generatedkeys/select/MyEntity.hbm.xml 2006-03-27 16:47:06 UTC (rev 9686) @@ -1,34 +0,0 @@ -<?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.oracle" default-access="field"> - - <class name="MyEntity" table="my_entity"> - - <id name="id"> - <generator class="select"/> - </id> - <property name="name"/> - </class> - - <database-object> - <create> - <![CDATA[CREATE OR REPLACE TRIGGER t_i_my_entity - BEFORE INSERT ON my_entity - FOR EACH ROW - BEGIN - select nvl( max(id), 0 ) + 1 - into :new.id - from my_entity; - END;]]> - </create> - <drop> - <![CDATA[DROP TRIGGER t_i_my_entity]]> - </drop> - <dialect-scope name="org.hibernate.dialect.Oracle9Dialect"/> - <dialect-scope name="org.hibernate.dialect.OracleDialect"/> - </database-object> - -</hibernate-mapping> \ No newline at end of file Copied: trunk/Hibernate3/test/org/hibernate/test/generatedkeys/select/MyEntity.hbm.xml (from rev 9675, 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:34:59 UTC (rev 9675) +++ trunk/Hibernate3/test/org/hibernate/test/generatedkeys/select/MyEntity.hbm.xml 2006-03-27 16:47:06 UTC (rev 9686) @@ -0,0 +1,36 @@ +<?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.select" default-access="field"> + + <class name="MyEntity" table="my_entity"> + + <id name="id"> + <generator class="select"/> + </id> + <natural-id> + <property name="name"/> + </natural-id> + </class> + + <database-object> + <create> + <![CDATA[CREATE OR REPLACE TRIGGER t_i_my_entity + BEFORE INSERT ON my_entity + FOR EACH ROW + BEGIN + select nvl( max(id), 0 ) + 1 + into :new.id + from my_entity; + END;]]> + </create> + <drop> + <![CDATA[DROP TRIGGER t_i_my_entity]]> + </drop> + <dialect-scope name="org.hibernate.dialect.Oracle9Dialect"/> + <dialect-scope name="org.hibernate.dialect.OracleDialect"/> + </database-object> + +</hibernate-mapping> \ No newline at end of file Modified: trunk/Hibernate3/test/org/hibernate/test/generatedkeys/select/MyEntity.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/generatedkeys/oracle/MyEntity.java 2006-03-02 03:14:31 UTC (rev 9531) +++ trunk/Hibernate3/test/org/hibernate/test/generatedkeys/select/MyEntity.java 2006-03-27 16:47:06 UTC (rev 9686) @@ -1,4 +1,4 @@ -package org.hibernate.test.generatedkeys.oracle; +package org.hibernate.test.generatedkeys.select; /** * @author <a href="mailto:st...@hi...">Steve Ebersole </a> Deleted: trunk/Hibernate3/test/org/hibernate/test/generatedkeys/select/OracleGeneratedKeysTest.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/generatedkeys/oracle/OracleGeneratedKeysTest.java 2006-03-02 03:14:31 UTC (rev 9531) +++ trunk/Hibernate3/test/org/hibernate/test/generatedkeys/select/OracleGeneratedKeysTest.java 2006-03-27 16:47:06 UTC (rev 9686) @@ -1,58 +0,0 @@ -package org.hibernate.test.generatedkeys.oracle; - -import org.hibernate.test.DatabaseSpecificTestCase; -import org.hibernate.Session; -import org.hibernate.cfg.Configuration; -import org.hibernate.cfg.Environment; -import org.hibernate.dialect.Oracle9Dialect; -import org.hibernate.dialect.Dialect; -import org.hibernate.dialect.DataDirectOracle9Dialect; -import junit.framework.Test; -import junit.framework.TestSuite; - -/** - * @author <a href="mailto:st...@hi...">Steve Ebersole </a> - */ -public class OracleGeneratedKeysTest extends DatabaseSpecificTestCase { - public OracleGeneratedKeysTest(String x) { - super( x ); - } - - 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) { - return ( dialect instanceof Oracle9Dialect ); - } - - protected String[] getMappings() { - return new String[] { - "generatedkeys/oracle/MyEntity.hbm.xml" - }; - } - - public static Test suite() { - return new TestSuite( OracleGeneratedKeysTest.class ); - } - - public void testJDBC3GetGeneratedKeysSupportOnOracle() { - if ( getDialect() instanceof DataDirectOracle9Dialect ) { - reportSkip( "DataDirect drivers known to not support JDBC3 getGeneratedKeys for Oracle", "oracle getGeneratedKeys support" ); - return; - } - Session session = openSession(); - session.beginTransaction(); - - MyEntity e = new MyEntity( "entity-1" ); - session.save( e ); - - // this insert should happen immediately! - assertEquals( "id not generated through forced insertion", new Long(1), e.getId() ); - - session.delete( e ); - session.getTransaction().commit(); - session.close(); - } -} Added: trunk/Hibernate3/test/org/hibernate/test/generatedkeys/select/SelectGeneratorTest.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/generatedkeys/oracle/SelectGeneratorTest.java 2006-03-02 03:14:31 UTC (rev 9531) +++ trunk/Hibernate3/test/org/hibernate/test/generatedkeys/select/SelectGeneratorTest.java 2006-03-27 16:47:06 UTC (rev 9686) @@ -0,0 +1,58 @@ +package org.hibernate.test.generatedkeys.select; + +import org.hibernate.test.DatabaseSpecificTestCase; +import org.hibernate.Session; +import org.hibernate.cfg.Configuration; +import org.hibernate.dialect.Oracle9Dialect; +import org.hibernate.dialect.Dialect; +import org.hibernate.dialect.DataDirectOracle9Dialect; +import junit.framework.Test; +import junit.framework.TestSuite; + +/** + * @author Steve Ebersole + */ +public class SelectGeneratorTest extends DatabaseSpecificTestCase { + public SelectGeneratorTest(String x) { + super( x ); + } + + // TODO : need to determine appropriate physical generation strategies for select-generator testing on other databases... + + protected void configure(Configuration cfg) { + super.configure( cfg ); + } + + public boolean appliesTo(Dialect dialect) { + return ( dialect instanceof Oracle9Dialect ); + } + + protected String[] getMappings() { + return new String[] { + "generatedkeys/select/MyEntity.hbm.xml" + }; + } + + public static Test suite() { + return new TestSuite( SelectGeneratorTest.class ); + } + + public void testJDBC3GetGeneratedKeysSupportOnOracle() { + if ( getDialect() instanceof DataDirectOracle9Dialect ) { + reportSkip( "DataDirect drivers known to not support JDBC3 getGeneratedKeys for Oracle", "oracle getGeneratedKeys support" ); + return; + } + Session session = openSession(); + session.beginTransaction(); + + MyEntity e = new MyEntity( "entity-1" ); + session.save( e ); + + // this insert should happen immediately! + assertEquals( "id not generated through forced insertion", new Long(1), e.getId() ); + + session.delete( e ); + session.getTransaction().commit(); + session.close(); + } +} Property changes on: trunk/Hibernate3/test/org/hibernate/test/generatedkeys/select/SelectGeneratorTest.java ___________________________________________________________________ Name: svn:keywords + Author Date Id Revision Name: svn:eol-style + native Added: trunk/Hibernate3/test/org/hibernate/test/generatedkeys/seqidentity/MyEntity.hbm.xml =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/generatedkeys/seqidentity/MyEntity.hbm.xml 2006-03-27 15:48:23 UTC (rev 9685) +++ trunk/Hibernate3/test/org/hibernate/test/generatedkeys/seqidentity/MyEntity.hbm.xml 2006-03-27 16:47:06 UTC (rev 9686) @@ -0,0 +1,18 @@ +<?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.seqidentity" default-access="field"> + + <class name="MyEntity" table="my_entity"> + + <id name="id"> + <generator class="sequence-identity"/> + </id> + <natural-id> + <property name="name"/> + </natural-id> + </class> + +</hibernate-mapping> \ No newline at end of file Added: trunk/Hibernate3/test/org/hibernate/test/generatedkeys/seqidentity/MyEntity.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/generatedkeys/seqidentity/MyEntity.java 2006-03-27 15:48:23 UTC (rev 9685) +++ trunk/Hibernate3/test/org/hibernate/test/generatedkeys/seqidentity/MyEntity.java 2006-03-27 16:47:06 UTC (rev 9686) @@ -0,0 +1,28 @@ +package org.hibernate.test.generatedkeys.seqidentity; + +/** + * @author <a href="mailto:st...@hi...">Steve Ebersole </a> + */ +public class MyEntity { + private Long id; + private String name; + + public MyEntity() { + } + + public MyEntity(String name) { + this.name = name; + } + + public Long getId() { + return id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} Added: trunk/Hibernate3/test/org/hibernate/test/generatedkeys/seqidentity/SequenceIdentityTest.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/generatedkeys/seqidentity/SequenceIdentityTest.java 2006-03-27 15:48:23 UTC (rev 9685) +++ trunk/Hibernate3/test/org/hibernate/test/generatedkeys/seqidentity/SequenceIdentityTest.java 2006-03-27 16:47:06 UTC (rev 9686) @@ -0,0 +1,54 @@ +package org.hibernate.test.generatedkeys.seqidentity; + +import org.hibernate.test.DatabaseSpecificTestCase; +import org.hibernate.Session; +import org.hibernate.cfg.Configuration; +import org.hibernate.dialect.Oracle9Dialect; +import org.hibernate.dialect.Dialect; +import org.hibernate.dialect.DataDirectOracle9Dialect; +import junit.framework.Test; +import junit.framework.TestSuite; + +/** + * @author Steve Ebersole + */ +public class SequenceIdentityTest extends DatabaseSpecificTestCase { + public SequenceIdentityTest(String x) { + super( x ); + } + + protected void configure(Configuration cfg) { + super.configure( cfg ); + } + + public boolean appliesTo(Dialect dialect) { + // the DataDirect driver for Oracle known to not support + // JDBC3 getGeneratedKeys... + return ( dialect instanceof Oracle9Dialect ) && ( ! ( dialect instanceof DataDirectOracle9Dialect ) ) ; + } + + protected String[] getMappings() { + return new String[] { + "generatedkeys/seqidentity/MyEntity.hbm.xml" + }; + } + + public static Test suite() { + return new TestSuite( SequenceIdentityTest.class ); + } + + public void testSequenceIdentityGenerator() { + Session session = openSession(); + session.beginTransaction(); + + MyEntity e = new MyEntity( "entity-1" ); + session.save( e ); + + // this insert should happen immediately! + assertEquals( "id not generated through forced insertion", new Long(1), e.getId() ); + + session.delete( e ); + session.getTransaction().commit(); + session.close(); + } +} |