HHH-18096 Support for JPA 3.2 database generator options
This commit is contained in:
parent
ee1c583d2e
commit
49964af5a9
|
@ -131,6 +131,14 @@ public class GenerationStrategyInterpreter {
|
|||
);
|
||||
}
|
||||
|
||||
final String options = tableGeneratorAnnotation.getString( "options" );
|
||||
if ( StringHelper.isNotEmpty( options ) ) {
|
||||
definitionBuilder.addParam(
|
||||
org.hibernate.id.enhanced.TableGenerator.TABLE_OPTIONS,
|
||||
options
|
||||
);
|
||||
}
|
||||
|
||||
definitionBuilder.addParam(
|
||||
org.hibernate.id.enhanced.TableGenerator.INCREMENT_PARAM,
|
||||
String.valueOf( tableGeneratorAnnotation.getInteger( "allocationSize" ) )
|
||||
|
|
|
@ -596,6 +596,8 @@ public class ManagedTypeProcessor {
|
|||
jaxbEntity, classDetails, xmlDocumentContext
|
||||
);
|
||||
|
||||
XmlAnnotationHelper.applyTableGenerators( jaxbEntity.getTableGenerators(), classDetails, xmlDocumentContext );
|
||||
|
||||
renderClass( classDetails, xmlDocumentContext );
|
||||
}
|
||||
|
||||
|
|
|
@ -131,6 +131,7 @@ import jakarta.persistence.SecondaryTables;
|
|||
import jakarta.persistence.SequenceGenerator;
|
||||
import jakarta.persistence.Table;
|
||||
import jakarta.persistence.TableGenerator;
|
||||
import jakarta.persistence.TableGenerators;
|
||||
import jakarta.persistence.Temporal;
|
||||
import jakarta.persistence.TemporalType;
|
||||
import jakarta.persistence.UniqueConstraint;
|
||||
|
@ -389,6 +390,27 @@ public class XmlAnnotationHelper {
|
|||
} );
|
||||
}
|
||||
|
||||
public static <A extends Annotation> void applyUniqueConstraints(
|
||||
List<JaxbUniqueConstraintImpl> jaxbUniqueConstraints,
|
||||
MutableAnnotationUsage<A> annotationUsage,
|
||||
XmlDocumentContext xmlDocumentContext) {
|
||||
if ( CollectionHelper.isEmpty( jaxbUniqueConstraints ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
final List<AnnotationUsage<UniqueConstraint>> uniqueConstraintUsages = new ArrayList<>( jaxbUniqueConstraints.size() );
|
||||
annotationUsage.setAttributeValue( "uniqueConstraints", uniqueConstraintUsages );
|
||||
|
||||
jaxbUniqueConstraints.forEach( (jaxbUniqueConstraint) -> {
|
||||
final MutableAnnotationUsage<UniqueConstraint> ucUsage =
|
||||
JpaAnnotations.UNIQUE_CONSTRAINT.createUsage( xmlDocumentContext.getModelBuildingContext() );
|
||||
XmlAnnotationHelper.applyOptionalAttribute( ucUsage, "name", jaxbUniqueConstraint.getName() );
|
||||
XmlAnnotationHelper.applyOptionalAttribute( ucUsage, "options", jaxbUniqueConstraint.getOptions() );
|
||||
ucUsage.setAttributeValue( "columnNames", jaxbUniqueConstraint.getColumnName() );
|
||||
uniqueConstraintUsages.add( ucUsage );
|
||||
} );
|
||||
}
|
||||
|
||||
public static <A extends Annotation> void applyIndexes(
|
||||
List<JaxbIndexImpl> jaxbIndexes,
|
||||
AnnotationTarget target,
|
||||
|
@ -405,6 +427,29 @@ public class XmlAnnotationHelper {
|
|||
applyOr( jaxbIndex, JaxbIndexImpl::getName, "name", indexAnn, JpaAnnotations.INDEX );
|
||||
applyOr( jaxbIndex, JaxbIndexImpl::getColumnList, "columnList", indexAnn, JpaAnnotations.INDEX );
|
||||
applyOr( jaxbIndex, JaxbIndexImpl::isUnique, "unique", indexAnn, JpaAnnotations.INDEX );
|
||||
applyOr( jaxbIndex, JaxbIndexImpl::getOptions, "options", indexAnn, JpaAnnotations.INDEX );
|
||||
indexes.add( indexAnn );
|
||||
} );
|
||||
|
||||
annotationUsage.setAttributeValue( "indexes", indexes );
|
||||
}
|
||||
|
||||
public static <A extends Annotation> void applyIndexes(
|
||||
List<JaxbIndexImpl> jaxbIndexes,
|
||||
MutableAnnotationUsage<A> annotationUsage,
|
||||
XmlDocumentContext xmlDocumentContext) {
|
||||
if ( CollectionHelper.isEmpty( jaxbIndexes ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
final List<AnnotationUsage<Index>> indexes = new ArrayList<>( jaxbIndexes.size() );
|
||||
jaxbIndexes.forEach( jaxbIndex -> {
|
||||
final MutableAnnotationUsage<Index> indexAnn =
|
||||
JpaAnnotations.INDEX.createUsage( xmlDocumentContext.getModelBuildingContext() );
|
||||
applyOr( jaxbIndex, JaxbIndexImpl::getName, "name", indexAnn, JpaAnnotations.INDEX );
|
||||
applyOr( jaxbIndex, JaxbIndexImpl::getColumnList, "columnList", indexAnn, JpaAnnotations.INDEX );
|
||||
applyOr( jaxbIndex, JaxbIndexImpl::isUnique, "unique", indexAnn, JpaAnnotations.INDEX );
|
||||
applyOr( jaxbIndex, JaxbIndexImpl::getOptions, "options", indexAnn, JpaAnnotations.INDEX );
|
||||
indexes.add( indexAnn );
|
||||
} );
|
||||
|
||||
|
@ -528,6 +573,24 @@ public class XmlAnnotationHelper {
|
|||
XmlProcessingHelper.applyAttributeIfSpecified( "options", jaxbGenerator.getOptions(), sequenceAnn );
|
||||
}
|
||||
|
||||
public static void applyTableGenerators(
|
||||
JaxbTableGeneratorImpl jaxbGenerator,
|
||||
MutableClassDetails classDetails,
|
||||
XmlDocumentContext xmlDocumentContext) {
|
||||
if ( jaxbGenerator == null ) {
|
||||
return;
|
||||
}
|
||||
|
||||
final MutableAnnotationUsage<TableGenerator> tableAnn = classDetails.replaceAnnotationUsage(
|
||||
JpaAnnotations.TABLE_GENERATOR,
|
||||
xmlDocumentContext.getModelBuildingContext()
|
||||
);
|
||||
|
||||
applyTableGeneratorAttributes( jaxbGenerator, tableAnn );
|
||||
applyUniqueConstraints( jaxbGenerator.getUniqueConstraints(), tableAnn, xmlDocumentContext );
|
||||
applyIndexes( jaxbGenerator.getIndexes(), tableAnn, xmlDocumentContext );
|
||||
}
|
||||
|
||||
public static void applyTableGenerator(
|
||||
JaxbTableGeneratorImpl jaxbGenerator,
|
||||
MutableMemberDetails memberDetails,
|
||||
|
@ -537,6 +600,14 @@ public class XmlAnnotationHelper {
|
|||
}
|
||||
|
||||
final MutableAnnotationUsage<TableGenerator> tableAnn = memberDetails.applyAnnotationUsage( JpaAnnotations.TABLE_GENERATOR, xmlDocumentContext.getModelBuildingContext() );
|
||||
applyTableGeneratorAttributes( jaxbGenerator, tableAnn );
|
||||
applyUniqueConstraints( jaxbGenerator.getUniqueConstraints(), memberDetails, tableAnn, xmlDocumentContext );
|
||||
applyIndexes( jaxbGenerator.getIndexes(), memberDetails, tableAnn, xmlDocumentContext );
|
||||
}
|
||||
|
||||
private static void applyTableGeneratorAttributes(
|
||||
JaxbTableGeneratorImpl jaxbGenerator,
|
||||
MutableAnnotationUsage<TableGenerator> tableAnn) {
|
||||
XmlProcessingHelper.applyAttributeIfSpecified( "name", jaxbGenerator.getName(), tableAnn );
|
||||
XmlProcessingHelper.applyAttributeIfSpecified( "table", jaxbGenerator.getTable(), tableAnn );
|
||||
XmlProcessingHelper.applyAttributeIfSpecified( "catalog", jaxbGenerator.getCatalog(), tableAnn );
|
||||
|
@ -546,8 +617,7 @@ public class XmlAnnotationHelper {
|
|||
XmlProcessingHelper.applyAttributeIfSpecified( "pkColumnValue", jaxbGenerator.getPkColumnValue(), tableAnn );
|
||||
XmlProcessingHelper.applyAttributeIfSpecified( "initialValue", jaxbGenerator.getInitialValue(), tableAnn );
|
||||
XmlProcessingHelper.applyAttributeIfSpecified( "allocationSize", jaxbGenerator.getInitialValue(), tableAnn );
|
||||
applyUniqueConstraints( jaxbGenerator.getUniqueConstraints(), memberDetails, tableAnn, xmlDocumentContext );
|
||||
applyIndexes( jaxbGenerator.getIndexes(), memberDetails, tableAnn, xmlDocumentContext );
|
||||
XmlProcessingHelper.applyAttributeIfSpecified( "options", jaxbGenerator.getOptions(), tableAnn );
|
||||
}
|
||||
|
||||
public static void applyUuidGenerator(
|
||||
|
|
|
@ -196,6 +196,11 @@ public class TableGenerator implements PersistentIdentifierGenerator {
|
|||
*/
|
||||
public static final int DEF_SEGMENT_LENGTH = 255;
|
||||
|
||||
/**
|
||||
* Configures the options of the table to use.
|
||||
*/
|
||||
public static final String TABLE_OPTIONS = "options";
|
||||
|
||||
private boolean storeLastUsedValue;
|
||||
|
||||
|
||||
|
@ -221,6 +226,7 @@ public class TableGenerator implements PersistentIdentifierGenerator {
|
|||
|
||||
private String contributor;
|
||||
|
||||
private String options;
|
||||
/**
|
||||
* Type mapping for the identifier.
|
||||
*
|
||||
|
@ -359,6 +365,7 @@ public class TableGenerator implements PersistentIdentifierGenerator {
|
|||
if ( contributor == null ) {
|
||||
contributor = "orm";
|
||||
}
|
||||
options = parameters.getProperty( TABLE_OPTIONS );
|
||||
}
|
||||
|
||||
private static OptimizerDescriptor determineOptimizationStrategy(Properties parameters, int incrementSize) {
|
||||
|
@ -727,6 +734,9 @@ public class TableGenerator implements PersistentIdentifierGenerator {
|
|||
qualifiedTableName.getObjectName(),
|
||||
(identifier) -> new Table( contributor, namespace, identifier, false )
|
||||
);
|
||||
if ( StringHelper.isNotEmpty( options ) ) {
|
||||
table.setOptions( options );
|
||||
}
|
||||
|
||||
final BasicTypeRegistry basicTypeRegistry = database.getTypeConfiguration().getBasicTypeRegistry();
|
||||
// todo : not sure the best solution here. do we add the columns if missing? other?
|
||||
|
|
|
@ -23,6 +23,10 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
|
|||
|
||||
@BaseUnitTest
|
||||
public class TableOptionsTest {
|
||||
|
||||
static final String TABLE_GENERATOR_NAME = "TEST_TABLE_GENERATOR";
|
||||
static final String TABLE_GENERATOR_OPTIONS = "option_0";
|
||||
|
||||
static final String TABLE_NAME = "PRIMARY_TABLE";
|
||||
static final String TABLE_OPTIONS = "option_1";
|
||||
|
||||
|
@ -53,7 +57,7 @@ public class TableOptionsTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testTableCommentAreCreated() throws Exception {
|
||||
public void testTableOptionsAreCreated() throws Exception {
|
||||
createSchema( TestEntity.class );
|
||||
assertTrue(
|
||||
tableCreationStatementContainsOptions( output, TABLE_NAME, TABLE_OPTIONS ),
|
||||
|
@ -67,12 +71,17 @@ public class TableOptionsTest {
|
|||
|
||||
assertTrue(
|
||||
tableCreationStatementContainsOptions( output, JOIN_TABLE_NAME, JOIN_TABLE_OPTIONS ),
|
||||
"Join Table " + JOIN_TABLE_NAME + " options has not been created "
|
||||
"JoinTable " + JOIN_TABLE_NAME + " options has not been created "
|
||||
);
|
||||
|
||||
assertTrue(
|
||||
tableCreationStatementContainsOptions( output, COLLECTION_TABLE_NAME, COLLECTION_TABLE_OPTIONS ),
|
||||
"Join Table " + COLLECTION_TABLE_NAME + " options has not been created "
|
||||
"JoinTable " + COLLECTION_TABLE_NAME + " options has not been created "
|
||||
);
|
||||
|
||||
assertTrue(
|
||||
tableCreationStatementContainsOptions( output, TABLE_GENERATOR_NAME, TABLE_GENERATOR_OPTIONS ),
|
||||
"TableGenerator " + COLLECTION_TABLE_NAME + " options has not been created "
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -98,6 +107,11 @@ public class TableOptionsTest {
|
|||
tableCreationStatementContainsOptions( output, COLLECTION_TABLE_NAME, COLLECTION_TABLE_OPTIONS ),
|
||||
"Join Table " + COLLECTION_TABLE_NAME + " options has not been created "
|
||||
);
|
||||
|
||||
assertTrue(
|
||||
tableCreationStatementContainsOptions( output, TABLE_GENERATOR_NAME, TABLE_GENERATOR_OPTIONS ),
|
||||
"TableGenerator " + TABLE_GENERATOR_NAME + " options has not been created "
|
||||
);
|
||||
}
|
||||
|
||||
private static boolean tableCreationStatementContainsOptions(
|
||||
|
@ -130,7 +144,7 @@ public class TableOptionsTest {
|
|||
.setHaltOnError( true )
|
||||
.setOutputFile( output.getAbsolutePath() )
|
||||
.setFormat( false )
|
||||
.create( EnumSet.of( TargetType.SCRIPT ), metadata );
|
||||
.createOnly( EnumSet.of( TargetType.SCRIPT ), metadata );
|
||||
}
|
||||
|
||||
private void createSchema(Class... annotatedClasses) {
|
||||
|
@ -146,7 +160,7 @@ public class TableOptionsTest {
|
|||
.setHaltOnError( true )
|
||||
.setOutputFile( output.getAbsolutePath() )
|
||||
.setFormat( false )
|
||||
.create( EnumSet.of( TargetType.SCRIPT ), metadata );
|
||||
.createOnly( EnumSet.of( TargetType.SCRIPT ), metadata );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,12 +7,15 @@ import jakarta.persistence.Column;
|
|||
import jakarta.persistence.ElementCollection;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.FetchType;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Index;
|
||||
import jakarta.persistence.JoinTable;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.SecondaryTable;
|
||||
import jakarta.persistence.Table;
|
||||
import jakarta.persistence.TableGenerator;
|
||||
|
||||
@Entity
|
||||
@Table(
|
||||
|
@ -25,6 +28,12 @@ import jakarta.persistence.Table;
|
|||
)
|
||||
public class TestEntity {
|
||||
@Id
|
||||
@TableGenerator(
|
||||
name = "id-table-generator",
|
||||
table = TableOptionsTest.TABLE_GENERATOR_NAME,
|
||||
options = TableOptionsTest.TABLE_GENERATOR_OPTIONS
|
||||
)
|
||||
@GeneratedValue(strategy = GenerationType.TABLE, generator = "id-table-generator")
|
||||
private Long id;
|
||||
|
||||
@Column(name = "NAME_COLUMN")
|
||||
|
|
|
@ -10,8 +10,11 @@
|
|||
<entity class="TestEntity" metadata-complete="true">
|
||||
<table name="PRIMARY_TABLE" options="option_1"/>
|
||||
<secondary-table name="SECOND_TABLE" options="option_2"/>
|
||||
<table-generator name="id-table-generator" table="TEST_TABLE_GENERATOR" options="option_0"/>
|
||||
<attributes>
|
||||
<id name="id"/>
|
||||
<id name="id">
|
||||
<generated-value strategy="TABLE" generator="id-table-generator"/>
|
||||
</id>
|
||||
<basic name="name">
|
||||
<column name="NAME_COLUMN"/>
|
||||
</basic>
|
||||
|
|
Loading…
Reference in New Issue