Skip to content

Commit

Permalink
HHH-9996 - Finish Derby database profile
Browse files Browse the repository at this point in the history
  • Loading branch information
dreab8 committed Sep 28, 2015
1 parent ac16e82 commit 8d3b2e7
Show file tree
Hide file tree
Showing 49 changed files with 750 additions and 217 deletions.
2 changes: 1 addition & 1 deletion databases/derby/matrix.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
//databaseProfile {
jdbcDependency 'org.apache.derby:derby:10.10.2.0'
jdbcDependency 'org.apache.derby:derby:10.11.1.1'

// testing {
// beforeSuite {
Expand Down
1 change: 0 additions & 1 deletion databases/derby/resources/hibernate.properties
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,5 @@ hibernate.max_fetch_depth 5
hibernate.cache.region_prefix hibernate.test
hibernate.cache.region.factory_class org.hibernate.testing.cache.CachingRegionFactory

javax.persistence.validation.mode=NONE
hibernate.service.allow_crawling=false
hibernate.session.events.log=true
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

import org.hibernate.Session;
import org.hibernate.internal.SessionImpl;
Expand Down Expand Up @@ -68,6 +69,7 @@ protected Class<?>[] getAnnotatedClasses() {
}

@Entity
@Table(name = "ChineseTakeawayRestaurant")
public class ChineseTakeawayRestaurant {

private long id;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,42 +6,32 @@
*/
package org.hibernate.id;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collections;
import java.util.Properties;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.boot.Metadata;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.boot.model.naming.ObjectNameNormalizer;
import org.hibernate.boot.model.relational.SimpleAuxiliaryDatabaseObject;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.boot.spi.MetadataBuildingContext;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
import org.hibernate.engine.jdbc.spi.JdbcServices;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.id.enhanced.SequenceStyleGenerator;
import org.hibernate.internal.SessionImpl;
import org.hibernate.jdbc.Work;
import org.hibernate.type.StandardBasicTypes;

import org.hibernate.testing.DialectChecks;
import org.hibernate.testing.RequiresDialectFeature;
import org.hibernate.testing.env.TestingDatabaseInfo;
import org.hibernate.testing.junit4.BaseUnitTestCase;
import org.hibernate.testing.boot.BasicTestingJdbcServiceImpl;
import org.hibernate.testing.boot.MetadataBuildingContextTestingImpl;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import org.hibernate.testing.DialectChecks;
import org.hibernate.testing.RequiresDialectFeature;
import org.hibernate.testing.boot.MetadataBuildingContextTestingImpl;
import org.hibernate.testing.junit4.BaseUnitTestCase;

import static org.junit.Assert.assertEquals;

/**
Expand All @@ -50,25 +40,21 @@
*
* @author Steve Ebersole
*/
@SuppressWarnings({ "deprecation" })
@RequiresDialectFeature( DialectChecks.SupportsSequences.class )
@SuppressWarnings({"deprecation"})
@RequiresDialectFeature(DialectChecks.SupportsSequences.class)
public class SequenceHiLoGeneratorNoIncrementTest extends BaseUnitTestCase {
private static final String TEST_SEQUENCE = "test_sequence";

private StandardServiceRegistry serviceRegistry;
private SessionFactoryImplementor sessionFactory;
private SequenceStyleGenerator generator;
private SessionImplementor session;
private SessionImplementor sessionImpl;
private SequenceValueExtractor sequenceValueExtractor;

@Before
public void setUp() throws Exception {
BasicTestingJdbcServiceImpl jdbcServices = new BasicTestingJdbcServiceImpl();
jdbcServices.prepare( false );

serviceRegistry = new StandardServiceRegistryBuilder()
.enableAutoClose()
.addService( JdbcEnvironment.class, jdbcServices.getJdbcEnvironment() )
.addService( JdbcServices.class, jdbcServices )
.applySetting( AvailableSettings.HBM2DDL_AUTO, "create-drop" )
.build();

Expand All @@ -94,13 +80,14 @@ protected MetadataBuildingContext getBuildingContext() {
generator.registerExportables( metadata.getDatabase() );

sessionFactory = (SessionFactoryImplementor) metadata.buildSessionFactory();
sequenceValueExtractor = new SequenceValueExtractor( sessionFactory.getDialect(), TEST_SEQUENCE );
}

@After
public void tearDown() throws Exception {
if(session != null && !session.isClosed()) {
((Session)session).close();
}
if ( sessionImpl != null && !sessionImpl.isClosed() ) {
((Session) sessionImpl).close();
}
if ( sessionFactory != null ) {
sessionFactory.close();
}
Expand All @@ -111,58 +98,49 @@ public void tearDown() throws Exception {

@Test
public void testHiLoAlgorithm() {
session = (SessionImpl) sessionFactory.openSession();
((Session)session).beginTransaction();
sessionImpl = (SessionImpl) sessionFactory.openSession();

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// initially sequence should be uninitialized
assertEquals( 0L, extractSequenceValue( (session) ) );
assertEquals( 0L, extractSequenceValue( (sessionImpl) ) );


// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// historically the hilo generators skipped the initial block of values;
// so the first generated id value is maxlo + 1, here be 4
Long generatedValue = (Long) generator.generate( session, null );
assertEquals( 1L, generatedValue.longValue() );
assertEquals( 1L, generateValue() );

// which should also perform the first read on the sequence which should set it to its "start with" value (1)
assertEquals( 1L, extractSequenceValue( (session) ) );
assertEquals( 1L, extractSequenceValue( (sessionImpl) ) );

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
generatedValue = (Long) generator.generate( session, null );
assertEquals( 2L, generatedValue.longValue() );
assertEquals( 2L, extractSequenceValue( (session) ) );
assertEquals( 2L, generateValue() );
assertEquals( 2L, extractSequenceValue( (sessionImpl) ) );

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
generatedValue = (Long) generator.generate( session, null );
assertEquals( 3L, generatedValue.longValue() );
assertEquals( 3L, extractSequenceValue( (session) ) );
assertEquals( 3L, generateValue() );
assertEquals( 3L, extractSequenceValue( (sessionImpl) ) );

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
generatedValue = (Long) generator.generate( session, null );
assertEquals( 4L, generatedValue.longValue() );
assertEquals( 4L, extractSequenceValue( (session) ) );
assertEquals( 4L, generateValue() );
assertEquals( 4L, extractSequenceValue( (sessionImpl) ) );

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
generatedValue = (Long) generator.generate( session, null );
assertEquals( 5L, generatedValue.longValue() );
assertEquals( 5L, extractSequenceValue( (session) ) );
assertEquals( 5L, generateValue() );
assertEquals( 5L, extractSequenceValue( (sessionImpl) ) );

((Session)session).getTransaction().commit();
((Session)session).close();
((Session) sessionImpl).close();
}

private long extractSequenceValue(final SessionImplementor session) {
class WorkImpl implements Work {
private long value;
public void execute(Connection connection) throws SQLException {

PreparedStatement query = session.getJdbcCoordinator().getStatementPreparer().prepareStatement( "select currval('" + TEST_SEQUENCE + "');" );
ResultSet resultSet = session.getJdbcCoordinator().getResultSetReturn().extract( query );
resultSet.next();
value = resultSet.getLong( 1 );
}
}
WorkImpl work = new WorkImpl();
( (Session) session ).doWork( work );
return work.value;
private long extractSequenceValue(SessionImplementor sessionImpl) {
return sequenceValueExtractor.extractSequenceValue( sessionImpl );
}

private long generateValue() {
Long generatedValue;
Transaction transaction = ((Session) sessionImpl).beginTransaction();
generatedValue = (Long) generator.generate( sessionImpl, null );
transaction.commit();
return generatedValue.longValue();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,10 @@
*/
package org.hibernate.id;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.boot.Metadata;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
Expand All @@ -22,33 +19,35 @@
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.internal.SessionImpl;
import org.hibernate.jdbc.Work;
import org.hibernate.type.StandardBasicTypes;

import org.hibernate.testing.DialectChecks;
import org.hibernate.testing.RequiresDialectFeature;
import org.hibernate.testing.junit4.BaseUnitTestCase;
import org.hibernate.testing.boot.MetadataBuildingContextTestingImpl;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import org.hibernate.testing.DialectChecks;
import org.hibernate.testing.RequiresDialectFeature;
import org.hibernate.testing.boot.MetadataBuildingContextTestingImpl;
import org.hibernate.testing.junit4.BaseUnitTestCase;

import static org.junit.Assert.assertEquals;

/**
* I went back to 3.3 source and grabbed the code/logic as it existed back then and crafted this
* unit test so that we can make sure the value keep being generated in the expected manner
*
*
* @author Steve Ebersole
*/
@SuppressWarnings({ "deprecation" })
@RequiresDialectFeature( DialectChecks.SupportsSequences.class )
@SuppressWarnings({"deprecation"})
@RequiresDialectFeature(DialectChecks.SupportsSequences.class)
public class SequenceHiLoGeneratorTest extends BaseUnitTestCase {
private static final String TEST_SEQUENCE = "test_sequence";

private StandardServiceRegistry serviceRegistry;
private SessionFactoryImplementor sessionFactory;
private SequenceHiLoGenerator generator;
private SessionImplementor sessionImpl;
private SequenceValueExtractor sequenceValueExtractor;

@Before
public void setUp() throws Exception {
Expand All @@ -62,7 +61,10 @@ public void setUp() throws Exception {
Properties properties = new Properties();
properties.setProperty( SequenceGenerator.SEQUENCE, TEST_SEQUENCE );
properties.setProperty( SequenceHiLoGenerator.MAX_LO, "3" );
properties.put( PersistentIdentifierGenerator.IDENTIFIER_NORMALIZER, buildingContext.getObjectNameNormalizer() );
properties.put(
PersistentIdentifierGenerator.IDENTIFIER_NORMALIZER,
buildingContext.getObjectNameNormalizer()
);

generator = new SequenceHiLoGenerator();
generator.configure( StandardBasicTypes.LONG, properties, serviceRegistry );
Expand All @@ -71,6 +73,7 @@ public void setUp() throws Exception {
generator.registerExportables( metadata.getDatabase() );

sessionFactory = (SessionFactoryImplementor) metadata.buildSessionFactory();
sequenceValueExtractor = new SequenceValueExtractor( sessionFactory.getDialect(), TEST_SEQUENCE );
}

@After
Expand All @@ -85,61 +88,50 @@ public void tearDown() throws Exception {

@Test
public void testHiLoAlgorithm() {
SessionImpl session = (SessionImpl) sessionFactory.openSession();
session.beginTransaction();
sessionImpl = (SessionImpl) sessionFactory.openSession();

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// initially sequence should be uninitialized
assertEquals( 0L, extractSequenceValue( session ) );
assertEquals( 0L, extractSequenceValue( sessionImpl ) );

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// historically the hilo generators skipped the initial block of values;
// so the first generated id value is maxlo + 1, here be 4
Long generatedValue = (Long) generator.generate( session, null );
assertEquals( 4L, generatedValue.longValue() );
assertEquals( 4L, generateValue() );
// which should also perform the first read on the sequence which should set it to its "start with" value (1)
assertEquals( 1L, extractSequenceValue( session ) );
assertEquals( 1L, extractSequenceValue( sessionImpl ) );

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
generatedValue = (Long) generator.generate( session, null );
assertEquals( 5L, generatedValue.longValue() );
assertEquals( 1L, extractSequenceValue( session ) );
assertEquals( 5L, generateValue() );
assertEquals( 1L, extractSequenceValue( sessionImpl ) );

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
generatedValue = (Long) generator.generate( session, null );
assertEquals( 6L, generatedValue.longValue() );
assertEquals( 1L, extractSequenceValue( session ) );
assertEquals( 6L, generateValue() );
assertEquals( 1L, extractSequenceValue( sessionImpl ) );

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
generatedValue = (Long) generator.generate( session, null );
assertEquals( 7L, generatedValue.longValue() );
assertEquals( 7L, generateValue() );
// unlike the newer strategies, the db value will not get update here. It gets updated on the next invocation
// after a clock over
assertEquals( 1L, extractSequenceValue( session ) );
assertEquals( 1L, extractSequenceValue( sessionImpl ) );

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
generatedValue = (Long) generator.generate( session, null );
assertEquals( 8L, generatedValue.longValue() );
assertEquals( 8L, generateValue() );
// this should force an increment in the sequence value
assertEquals( 2L, extractSequenceValue( session ) );
assertEquals( 2L, extractSequenceValue( sessionImpl ) );

session.getTransaction().commit();
session.close();
((Session) sessionImpl).close();
}

private long extractSequenceValue(final SessionImplementor session) {
class WorkImpl implements Work {
private long value;
private long extractSequenceValue(SessionImplementor sessionImpl) {
return sequenceValueExtractor.extractSequenceValue( sessionImpl );
}

public void execute(Connection connection) throws SQLException {
PreparedStatement query = session.getJdbcCoordinator().getStatementPreparer().prepareStatement( "select currval('" + TEST_SEQUENCE + "');" );
ResultSet resultSet = session.getJdbcCoordinator().getResultSetReturn().extract( query );
resultSet.next();
value = resultSet.getLong( 1 );
}
}
WorkImpl work = new WorkImpl();
( (Session) session ).doWork( work );
return work.value;
private long generateValue() {
Long generatedValue;
Transaction transaction = ((Session) sessionImpl).beginTransaction();
generatedValue = (Long) generator.generate( sessionImpl, null );
transaction.commit();
return generatedValue.longValue();
}
}
Loading

0 comments on commit 8d3b2e7

Please sign in to comment.