We currently mirgate our application from Hibernate 3.3 to Hibernate 4.3.7. May anyone can help me with an issue which we have with hibernate 4 and programmatic SequenceStyleGenerator.
In Hibernate 3.3 we created IdentifierGenerator as followed
final Properties properties = new Properties(); properties.setProperty( "sequence_name", sequenceName ); properties.setProperty( "increment_size", "20" ); properties.setProperty( "optimizer", "pooled" ); return IdentifierGeneratorFactory.create( "org.hibernate.id.enhanced.SequenceStyleGenerator", Hibernate.LONG, properties, new FesadOracleDialect() );
In Hibernate 4 we create a org.hibernate.id.IdentifierGenerator as an instance of org.hibernate.id.enhanced.SequenceStyleGenerator:
final Properties properties = new Properties(); properties.setProperty( "sequence_name", sequenceName ); properties.setProperty( "increment_size", "20" ); properties.setProperty( "optimizer", "pooled" ); org.hibernate.id.enhanced.SequenceStyleGenerator gen = new org.hibernate.id.enhanced.SequenceStyleGenerator(); gen.configure( new LongType(), properties, new FesadOracleDialect() ); return gen;
Since Hibernate 4 org.hibernate.id.enhanced.SequenceStyleGenerator#determineSequenceName requires an instance of an ObjectNameNormalizer stored in the properties. If ObjectNameNormalizer isn't stored in the properties we get a NPE at org.hibernate.id.enhanced.SequenceStyleGenerator:286 (see following snippet lineno 7).
protected String determineSequenceName(Properties params, Dialect dialect) { final String sequencePerEntitySuffix = ConfigurationHelper.getString( CONFIG_SEQUENCE_PER_ENTITY_SUFFIX, params, DEF_SEQUENCE_SUFFIX ); // JPA_ENTITY_NAME value honors <class ... entity-name="..."> (HBM) and @Entity#name (JPA) overrides. String sequenceName = ConfigurationHelper.getBoolean( CONFIG_PREFER_SEQUENCE_PER_ENTITY, params, false ) ? params.getProperty( JPA_ENTITY_NAME ) + sequencePerEntitySuffix : DEF_SEQUENCE_NAME; final ObjectNameNormalizer normalizer = (ObjectNameNormalizer) params.get( IDENTIFIER_NORMALIZER ); sequenceName = ConfigurationHelper.getString( SEQUENCE_PARAM, params, sequenceName ); if ( sequenceName.indexOf( '.' ) < 0 ) { sequenceName = normalizer.normalizeIdentifierQuoting( sequenceName ); final String schemaName = params.getProperty( SCHEMA ); final String catalogName = params.getProperty( CATALOG ); sequenceName = Table.qualify( dialect.quote( catalogName ), dialect.quote( schemaName ), dialect.quote( sequenceName ) ); } // if already qualified there is not much we can do in a portable manner so we pass it // through and assume the user has set up the name correctly. return sequenceName; }
So how can we get an instance of this ObjectNameNormalizer? For testing we added our own implementation of an ObjectNameNormalizer... but is this the right way to do it?
final Properties properties = new Properties(); properties.setProperty( "sequence_name", sequenceName ); properties.setProperty( "increment_size", "20" ); properties.setProperty( "optimizer", "pooled" ); // TODO ist das der richtige Weg um den ObjectNameNormalizer zu übergeben??? properties.put( PersistentIdentifierGenerator.IDENTIFIER_NORMALIZER, new ObjectNameNormalizer() { @Override protected boolean isUseQuotedIdentifiersGlobally() { return false; } @Override protected NamingStrategy getNamingStrategy() { return null; } @Override protected NamingStrategyDelegator getNamingStrategyDelegator() { return null; } }); org.hibernate.id.enhanced.SequenceStyleGenerator gen = new org.hibernate.id.enhanced.SequenceStyleGenerator(); gen.configure( new LongType(), properties, new FesadOracleDialect() ); return gen;
Comments