下面列出了怎么用org.hibernate.id.enhanced.SequenceStyleGenerator的API类实例代码及写法,或者点击链接到github查看源代码。
/**
* Constructs a new DefaultIdentifierGeneratorFactory.
*/
@SuppressWarnings("deprecation")
public DefaultIdentifierGeneratorFactory() {
register( "uuid2", UUIDGenerator.class );
register( "guid", GUIDGenerator.class ); // can be done with UUIDGenerator + strategy
register( "uuid", UUIDHexGenerator.class ); // "deprecated" for new use
register( "uuid.hex", UUIDHexGenerator.class ); // uuid.hex is deprecated
register( "assigned", Assigned.class );
register( "identity", IdentityGenerator.class );
register( "select", SelectGenerator.class );
register( "sequence", SequenceStyleGenerator.class );
register( "seqhilo", SequenceHiLoGenerator.class );
register( "increment", IncrementGenerator.class );
register( "foreign", ForeignGenerator.class );
register( "sequence-identity", SequenceIdentityGenerator.class );
register( "enhanced-sequence", SequenceStyleGenerator.class );
register( "enhanced-table", TableGenerator.class );
}
/**
* Determine the name of the sequence (or table if this resolves to a physical table)
* to use.
*
* @param params The params supplied in the generator config (plus some standard useful extras).
* @return The sequence name
*/
static QualifiedName determineSequenceName(Properties params, ServiceRegistry serviceRegistry) {
final String sequencePerEntitySuffix = ConfigurationHelper.getString( SequenceStyleGenerator.CONFIG_SEQUENCE_PER_ENTITY_SUFFIX, params, SequenceStyleGenerator.DEF_SEQUENCE_SUFFIX );
String fallbackSequenceName = SequenceStyleGenerator.DEF_SEQUENCE_NAME;
final Boolean preferGeneratorNameAsDefaultName = serviceRegistry.getService( ConfigurationService.class )
.getSetting( Settings.PREFER_GENERATOR_NAME_AS_DEFAULT_SEQUENCE_NAME, StandardConverters.BOOLEAN, true );
if ( preferGeneratorNameAsDefaultName ) {
final String generatorName = params.getProperty( IdentifierGenerator.GENERATOR_NAME );
if ( StringHelper.isNotEmpty( generatorName ) ) {
fallbackSequenceName = generatorName;
}
}
// JPA_ENTITY_NAME value honors <class ... entity-name="..."> (HBM) and @Entity#name (JPA) overrides.
final String defaultSequenceName = ConfigurationHelper.getBoolean( SequenceStyleGenerator.CONFIG_PREFER_SEQUENCE_PER_ENTITY, params, false )
? params.getProperty( SequenceStyleGenerator.JPA_ENTITY_NAME ) + sequencePerEntitySuffix
: fallbackSequenceName;
final String sequenceName = ConfigurationHelper.getString( SequenceStyleGenerator.SEQUENCE_PARAM, params, defaultSequenceName );
if ( sequenceName.contains( "." ) ) {
return QualifiedNameParser.INSTANCE.parse( sequenceName );
}
else {
JdbcEnvironment jdbcEnvironment = serviceRegistry.getService( JdbcEnvironment.class );
// todo : need to incorporate implicit catalog and schema names
final Identifier catalog = jdbcEnvironment.getIdentifierHelper().toIdentifier(
ConfigurationHelper.getString( CATALOG, params )
);
final Identifier schema = jdbcEnvironment.getIdentifierHelper().toIdentifier(
ConfigurationHelper.getString( SCHEMA, params )
);
return new QualifiedNameParser.NameParts(
catalog,
schema,
jdbcEnvironment.getIdentifierHelper().toIdentifier( sequenceName )
);
}
}
private static IdentifierGenerator augmentWithReactiveGenerator(IdentifierGenerator generator, Type type, Properties params, ServiceRegistryImplementor serviceRegistry) {
ReactiveIdentifierGenerator<?> reactiveGenerator;
if (generator instanceof SequenceStyleGenerator) {
DatabaseStructure structure = ((SequenceStyleGenerator) generator).getDatabaseStructure();
if (structure instanceof TableStructure) {
reactiveGenerator = new TableReactiveIdentifierGenerator(true);
}
else if (structure instanceof SequenceStructure) {
reactiveGenerator = new SequenceReactiveIdentifierGenerator();
}
else {
throw new IllegalStateException("unknown structure type");
}
}
else if (generator instanceof TableGenerator) {
reactiveGenerator = new TableReactiveIdentifierGenerator(false);
}
else if (generator instanceof SequenceGenerator) {
reactiveGenerator = new SequenceReactiveIdentifierGenerator();
}
else if (generator instanceof SelectGenerator) {
//TODO: this is easy to fix!
throw new HibernateException("SelectGenerator is not yet supported in Hibernate Reactive");
}
else {
//nothing to do
return generator;
}
((Configurable) reactiveGenerator).configure( type, params, serviceRegistry );
return new ReactiveGeneratorWrapper<>( reactiveGenerator, generator );
}
private List<String> getCreateTableStrings(
Table table, Metadata metadata, Iterable<Column> keyColumns) {
// Get the comma separated string of the primary keys of the table.
String primaryKeyColNames = StreamSupport.stream(keyColumns.spliterator(), false)
.map(Column::getQuotedName)
.collect(Collectors.joining(","));
// Get the comma separated string of all columns of the table.
Iterable<Column> columnIterable = () -> (Iterator<Column>) table.getColumnIterator();
String allColumnNames = StreamSupport.stream(columnIterable.spliterator(), false)
.map(column -> buildColumnTypeString(column, metadata))
.collect(Collectors.joining(","));
ArrayList<String> statements = new ArrayList<>();
// Build the Create Table string.
String createTableString = MessageFormat.format(
CREATE_TABLE_TEMPLATE,
table.getQuotedName(),
allColumnNames,
primaryKeyColNames,
getInterleavedClause(table, metadata));
statements.add(createTableString);
if (table.getName().equals(SequenceStyleGenerator.DEF_SEQUENCE_NAME)) {
// Caches the INSERT statement since DML statements must be run after a DDL batch.
addStatementAfterDdlBatch(
metadata,
"INSERT INTO " + SequenceStyleGenerator.DEF_SEQUENCE_NAME + " ("
+ SequenceStyleGenerator.DEF_VALUE_COLUMN + ") VALUES(1)");
}
return statements;
}
/**
* The class (which implements {@link org.hibernate.id.IdentifierGenerator})
* which acts as this dialects native generation strategy.
* <p/>
* Comes into play whenever the user specifies the native generator.
*
* @return The native generator class.
* @deprecated use {@link #getNativeIdentifierGeneratorStrategy()} instead
*/
@Deprecated
public Class getNativeIdentifierGeneratorClass() {
if ( getIdentityColumnSupport().supportsIdentityColumns() ) {
return IdentityGenerator.class;
}
else {
return SequenceStyleGenerator.class;
}
}
@Override
public String determineGeneratorName(GenerationType generationType, GeneratorNameDeterminationContext context) {
switch ( generationType ) {
case IDENTITY: {
return "identity";
}
case SEQUENCE: {
return org.hibernate.id.enhanced.SequenceStyleGenerator.class.getName();
}
case TABLE: {
return org.hibernate.id.enhanced.TableGenerator.class.getName();
}
default: {
// AUTO
if ( "increment".equalsIgnoreCase( context.getGeneratedValueGeneratorName() ) ) {
return IncrementGenerator.class.getName();
}
final Class javaType = context.getIdType();
if ( UUID.class.isAssignableFrom( javaType ) ) {
return UUIDGenerator.class.getName();
}
return org.hibernate.id.enhanced.SequenceStyleGenerator.class.getName();
}
}
}
@Override
public void interpretSequenceGenerator(
SequenceGenerator sequenceGeneratorAnnotation,
IdentifierGeneratorDefinition.Builder definitionBuilder) {
definitionBuilder.setName( sequenceGeneratorAnnotation.name() );
definitionBuilder.setStrategy( SequenceStyleGenerator.class.getName() );
if ( !BinderHelper.isEmptyAnnotationValue( sequenceGeneratorAnnotation.catalog() ) ) {
definitionBuilder.addParam(
PersistentIdentifierGenerator.CATALOG,
sequenceGeneratorAnnotation.catalog()
);
}
if ( !BinderHelper.isEmptyAnnotationValue( sequenceGeneratorAnnotation.schema() ) ) {
definitionBuilder.addParam(
PersistentIdentifierGenerator.SCHEMA,
sequenceGeneratorAnnotation.schema()
);
}
if ( !BinderHelper.isEmptyAnnotationValue( sequenceGeneratorAnnotation.sequenceName() ) ) {
definitionBuilder.addParam(
SequenceStyleGenerator.SEQUENCE_PARAM,
sequenceGeneratorAnnotation.sequenceName()
);
}
definitionBuilder.addParam(
SequenceStyleGenerator.INCREMENT_PARAM,
String.valueOf( sequenceGeneratorAnnotation.allocationSize() )
);
definitionBuilder.addParam(
SequenceStyleGenerator.INITIAL_PARAM,
String.valueOf( sequenceGeneratorAnnotation.initialValue() )
);
}
public void testNormalBoundary() {
EntityPersister persister = sfi().getEntityPersister( Entity.class.getName() );
assertClassAssignability( SequenceStyleGenerator.class, persister.getIdentifierGenerator().getClass() );
SequenceStyleGenerator generator = ( SequenceStyleGenerator ) persister.getIdentifierGenerator();
assertClassAssignability( OptimizerFactory.PooledOptimizer.class, generator.getOptimizer().getClass() );
OptimizerFactory.PooledOptimizer optimizer = ( OptimizerFactory.PooledOptimizer ) generator.getOptimizer();
int increment = optimizer.getIncrementSize();
Entity[] entities = new Entity[ increment + 1 ];
Session s = openSession();
s.beginTransaction();
for ( int i = 0; i < increment; i++ ) {
entities[i] = new Entity( "" + ( i + 1 ) );
s.save( entities[i] );
assertEquals( 2, generator.getDatabaseStructure().getTimesAccessed() ); // initialization calls seq twice
assertEquals( increment + 1, optimizer.getLastSourceValue() ); // initialization calls seq twice
assertEquals( i + 1, optimizer.getLastValue() );
assertEquals( increment + 1, optimizer.getLastSourceValue() );
}
// now force a "clock over"
entities[ increment ] = new Entity( "" + increment );
s.save( entities[ increment ] );
assertEquals( 3, generator.getDatabaseStructure().getTimesAccessed() ); // initialization (2) + clock over
assertEquals( ( increment * 2 ) + 1, optimizer.getLastSourceValue() ); // initialization (2) + clock over
assertEquals( increment + 1, optimizer.getLastValue() );
s.getTransaction().commit();
s.beginTransaction();
for ( int i = 0; i < entities.length; i++ ) {
assertEquals( i + 1, entities[i].getId().intValue() );
s.delete( entities[i] );
}
s.getTransaction().commit();
s.close();
}
public void testNormalBoundary() {
EntityPersister persister = sfi().getEntityPersister( Entity.class.getName() );
assertClassAssignability( SequenceStyleGenerator.class, persister.getIdentifierGenerator().getClass() );
SequenceStyleGenerator generator = ( SequenceStyleGenerator ) persister.getIdentifierGenerator();
int count = 5;
Entity[] entities = new Entity[count];
Session s = openSession();
s.beginTransaction();
for ( int i = 0; i < count; i++ ) {
entities[i] = new Entity( "" + ( i + 1 ) );
s.save( entities[i] );
long expectedId = i + 1;
assertEquals( expectedId, entities[i].getId().longValue() );
assertEquals( expectedId, generator.getDatabaseStructure().getTimesAccessed() );
assertEquals( expectedId, generator.getOptimizer().getLastSourceValue() );
}
s.getTransaction().commit();
s.beginTransaction();
for ( int i = 0; i < count; i++ ) {
assertEquals( i + 1, entities[i].getId().intValue() );
s.delete( entities[i] );
}
s.getTransaction().commit();
s.close();
}
public void testNormalBoundary() {
EntityPersister persister = sfi().getEntityPersister( Entity.class.getName() );
assertClassAssignability( SequenceStyleGenerator.class, persister.getIdentifierGenerator().getClass() );
SequenceStyleGenerator generator = ( SequenceStyleGenerator ) persister.getIdentifierGenerator();
assertClassAssignability( OptimizerFactory.HiLoOptimizer.class, generator.getOptimizer().getClass() );
OptimizerFactory.HiLoOptimizer optimizer = ( OptimizerFactory.HiLoOptimizer ) generator.getOptimizer();
int increment = optimizer.getIncrementSize();
Entity[] entities = new Entity[ increment + 1 ];
Session s = openSession();
s.beginTransaction();
for ( int i = 0; i < increment; i++ ) {
entities[i] = new Entity( "" + ( i + 1 ) );
s.save( entities[i] );
assertEquals( 1, generator.getDatabaseStructure().getTimesAccessed() ); // initialization
assertEquals( 1, optimizer.getLastSourceValue() ); // initialization
assertEquals( i + 1, optimizer.getLastValue() );
assertEquals( increment + 1, optimizer.getHiValue() );
}
// now force a "clock over"
entities[ increment ] = new Entity( "" + increment );
s.save( entities[ increment ] );
assertEquals( 2, generator.getDatabaseStructure().getTimesAccessed() ); // initialization
assertEquals( 2, optimizer.getLastSourceValue() ); // initialization
assertEquals( increment + 1, optimizer.getLastValue() );
assertEquals( ( increment * 2 ) + 1, optimizer.getHiValue() );
s.getTransaction().commit();
s.beginTransaction();
for ( int i = 0; i < entities.length; i++ ) {
assertEquals( i + 1, entities[i].getId().intValue() );
s.delete( entities[i] );
}
s.getTransaction().commit();
s.close();
}
public void testNormalBoundary() {
EntityPersister persister = sfi().getEntityPersister( Entity.class.getName() );
assertClassAssignability( SequenceStyleGenerator.class, persister.getIdentifierGenerator().getClass() );
SequenceStyleGenerator generator = ( SequenceStyleGenerator ) persister.getIdentifierGenerator();
int count = 5;
Entity[] entities = new Entity[count];
Session s = openSession();
s.beginTransaction();
for ( int i = 0; i < count; i++ ) {
entities[i] = new Entity( "" + ( i + 1 ) );
s.save( entities[i] );
long expectedId = i + 1;
assertEquals( expectedId, entities[i].getId().longValue() );
assertEquals( expectedId, generator.getDatabaseStructure().getTimesAccessed() );
assertEquals( expectedId, generator.getOptimizer().getLastSourceValue() );
}
s.getTransaction().commit();
s.beginTransaction();
for ( int i = 0; i < count; i++ ) {
assertEquals( i + 1, entities[i].getId().intValue() );
s.delete( entities[i] );
}
s.getTransaction().commit();
s.close();
}
/**
* Test all params defaulted with a dialect supporting sequences
*/
public void testDefaultedSequenceBackedConfiguration() {
Dialect dialect = new SequenceDialect();
Properties props = new Properties();
SequenceStyleGenerator generator = new SequenceStyleGenerator();
generator.configure( Hibernate.LONG, props, dialect );
assertClassAssignability( SequenceStructure.class, generator.getDatabaseStructure().getClass() );
assertClassAssignability( OptimizerFactory.NoopOptimizer.class, generator.getOptimizer().getClass() );
assertEquals( SequenceStyleGenerator.DEF_SEQUENCE_NAME, generator.getDatabaseStructure().getName() );
}
/**
* Test all params defaulted with a dialect which does not support sequences
*/
public void testDefaultedTableBackedConfiguration() {
Dialect dialect = new TableDialect();
Properties props = new Properties();
SequenceStyleGenerator generator = new SequenceStyleGenerator();
generator.configure( Hibernate.LONG, props, dialect );
assertClassAssignability( TableStructure.class, generator.getDatabaseStructure().getClass() );
assertClassAssignability( OptimizerFactory.NoopOptimizer.class, generator.getOptimizer().getClass() );
assertEquals( SequenceStyleGenerator.DEF_SEQUENCE_NAME, generator.getDatabaseStructure().getName() );
}
/**
* Test default optimizer selection for table backed generators
* based on the configured increment size. Here we always prefer
* pooled.
*/
public void testDefaultOptimizerBasedOnIncrementBackedByTable() {
Properties props = new Properties();
props.setProperty( SequenceStyleGenerator.INCREMENT_PARAM, "10" );
Dialect dialect = new TableDialect();
SequenceStyleGenerator generator = new SequenceStyleGenerator();
generator.configure( Hibernate.LONG, props, dialect );
assertClassAssignability( TableStructure.class, generator.getDatabaseStructure().getClass() );
assertClassAssignability( OptimizerFactory.PooledOptimizer.class, generator.getOptimizer().getClass() );
assertEquals( SequenceStyleGenerator.DEF_SEQUENCE_NAME, generator.getDatabaseStructure().getName() );
}
/**
* Test forcing of table as backing strucuture with dialect supporting sequences
*/
public void testForceTableUse() {
Dialect dialect = new SequenceDialect();
Properties props = new Properties();
props.setProperty( SequenceStyleGenerator.FORCE_TBL_PARAM, "true" );
SequenceStyleGenerator generator = new SequenceStyleGenerator();
generator.configure( Hibernate.LONG, props, dialect );
assertClassAssignability( TableStructure.class, generator.getDatabaseStructure().getClass() );
assertClassAssignability( OptimizerFactory.NoopOptimizer.class, generator.getOptimizer().getClass() );
assertEquals( SequenceStyleGenerator.DEF_SEQUENCE_NAME, generator.getDatabaseStructure().getName() );
}
static String determineValueColumnNameForSequenceEmulation(Properties params, JdbcEnvironment jdbcEnvironment) {
final String name = ConfigurationHelper.getString( SequenceStyleGenerator.VALUE_COLUMN_PARAM, params, SequenceStyleGenerator.DEF_VALUE_COLUMN );
return jdbcEnvironment.getIdentifierHelper().toIdentifier( name ).render( jdbcEnvironment.getDialect() );
}
protected int determineInitialValueForSequenceEmulation(Properties params) {
return ConfigurationHelper.getInt( SequenceStyleGenerator.INITIAL_PARAM, params, SequenceStyleGenerator.DEFAULT_INITIAL_VALUE );
}
@SuppressWarnings("unchecked")
protected void bindSimpleId(PersistentProperty identifier, RootClass entity,
InFlightMetadataCollector mappings, Identity mappedId, String sessionFactoryBeanName) {
Mapping mapping = getMapping(identifier.getOwner());
boolean useSequence = mapping != null && mapping.isTablePerConcreteClass();
// create the id value
SimpleValue id = new SimpleValue(metadataBuildingContext, entity.getTable());
Property idProperty = new Property();
idProperty.setName(identifier.getName());
idProperty.setValue(id);
entity.setDeclaredIdentifierProperty(idProperty);
// set identifier on entity
Properties params = new Properties();
entity.setIdentifier(id);
if (mappedId == null) {
// configure generator strategy
id.setIdentifierGeneratorStrategy(useSequence ? "sequence-identity" : "native");
} else {
String generator = mappedId.getGenerator();
if("native".equals(generator) && useSequence) {
generator = "sequence-identity";
}
id.setIdentifierGeneratorStrategy(generator);
params.putAll(mappedId.getParams());
if(params.containsKey(SEQUENCE_KEY)) {
params.put(SequenceStyleGenerator.SEQUENCE_PARAM, params.getProperty(SEQUENCE_KEY));
}
if ("assigned".equals(generator)) {
id.setNullValue("undefined");
}
}
String schemaName = getSchemaName(mappings);
String catalogName = getCatalogName(mappings);
params.put(PersistentIdentifierGenerator.IDENTIFIER_NORMALIZER, this.metadataBuildingContext.getObjectNameNormalizer());
if (schemaName != null) {
params.setProperty(PersistentIdentifierGenerator.SCHEMA, schemaName);
}
if (catalogName != null) {
params.setProperty(PersistentIdentifierGenerator.CATALOG, catalogName);
}
id.setIdentifierGeneratorProperties(params);
// bind value
bindSimpleValue(identifier, null, id, EMPTY_PATH, mappings, sessionFactoryBeanName);
// create property
Property prop = new Property();
prop.setValue(id);
// bind property
bindProperty(identifier, prop, mappings);
// set identifier property
entity.setIdentifierProperty(prop);
id.getTable().setIdentifierValue(id);
}
protected void bindSimpleValue(PersistentProperty grailsProp,
PersistentProperty parentProperty, SimpleValue simpleValue,
String path, PropertyConfig propertyConfig, String sessionFactoryBeanName) {
setTypeForPropertyConfig(grailsProp, simpleValue, propertyConfig);
final PropertyConfig mappedForm = (PropertyConfig) grailsProp.getMapping().getMappedForm();
if (mappedForm.isDerived() && !(grailsProp instanceof TenantId)) {
Formula formula = new Formula();
formula.setFormula(propertyConfig.getFormula());
simpleValue.addFormula(formula);
} else {
Table table = simpleValue.getTable();
boolean hasConfig = propertyConfig != null;
String generator = hasConfig ? propertyConfig.getGenerator() : null;
if(generator != null) {
simpleValue.setIdentifierGeneratorStrategy(generator);
Properties params = propertyConfig.getTypeParams();
if(params != null) {
Properties generatorProps = new Properties();
generatorProps.putAll(params);
if(generatorProps.containsKey(SEQUENCE_KEY)) {
generatorProps.put(SequenceStyleGenerator.SEQUENCE_PARAM, generatorProps.getProperty(SEQUENCE_KEY));
}
simpleValue.setIdentifierGeneratorProperties( generatorProps );
}
}
// Add the column definitions for this value/property. Note that
// not all custom mapped properties will have column definitions,
// in which case we still need to create a Hibernate column for
// this value.
List<?> columnDefinitions = hasConfig ? propertyConfig.getColumns()
: Arrays.asList(new Object[] { null });
if (columnDefinitions.isEmpty()) {
columnDefinitions = Arrays.asList(new Object[] { null });
}
for (Object columnDefinition : columnDefinitions) {
ColumnConfig cc = (ColumnConfig) columnDefinition;
Column column = new Column();
// Check for explicitly mapped column name and SQL type.
if (cc != null) {
if (cc.getName() != null) {
column.setName(cc.getName());
}
if (cc.getSqlType() != null) {
column.setSqlType(cc.getSqlType());
}
}
column.setValue(simpleValue);
if (cc != null) {
if (cc.getLength() != -1) {
column.setLength(cc.getLength());
}
if (cc.getPrecision() != -1) {
column.setPrecision(cc.getPrecision());
}
if (cc.getScale() != -1) {
column.setScale(cc.getScale());
}
if(!mappedForm.isUniqueWithinGroup()) {
column.setUnique(cc.isUnique());
}
}
bindColumn(grailsProp, parentProperty, column, cc, path, table, sessionFactoryBeanName);
if (table != null) {
table.addColumn(column);
}
simpleValue.addColumn(column);
}
}
}
@Override
public void configure(
Type type,
Properties params,
ServiceRegistry serviceRegistry)
throws MappingException {
final JdbcEnvironment jdbcEnvironment = serviceRegistry.getService(
JdbcEnvironment.class
);
final Dialect dialect = jdbcEnvironment.getDialect();
final ConfigurationService configurationService = serviceRegistry.getService(
ConfigurationService.class
);
String globalEntityIdentifierPrefix = configurationService.getSetting(
"entity.identifier.prefix",
String.class,
"SEQ_"
);
sequencePrefix = ConfigurationHelper.getString(
SEQUENCE_PREFIX,
params,
globalEntityIdentifierPrefix
);
final String sequencePerEntitySuffix = ConfigurationHelper.getString(
SequenceStyleGenerator.CONFIG_SEQUENCE_PER_ENTITY_SUFFIX,
params,
SequenceStyleGenerator.DEF_SEQUENCE_SUFFIX
);
boolean preferSequencePerEntity = ConfigurationHelper.getBoolean(
SequenceStyleGenerator.CONFIG_PREFER_SEQUENCE_PER_ENTITY,
params,
false
);
final String defaultSequenceName = preferSequencePerEntity
? params.getProperty(JPA_ENTITY_NAME) + sequencePerEntitySuffix
: SequenceStyleGenerator.DEF_SEQUENCE_NAME;
sequenceCallSyntax = dialect.getSequenceNextValString(
ConfigurationHelper.getString(
SequenceStyleGenerator.SEQUENCE_PARAM,
params,
defaultSequenceName
)
);
}