HHH-18057 Support for JPA 3.2 column options
This commit is contained in:
parent
79e7cc6f01
commit
ee1c583d2e
|
@ -97,6 +97,8 @@ public class AnnotatedColumn {
|
|||
|
||||
private AnnotatedColumns parent;
|
||||
|
||||
private String options;
|
||||
|
||||
public AnnotatedColumns getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
@ -263,6 +265,8 @@ public class AnnotatedColumn {
|
|||
for ( CheckConstraint constraint : checkConstraints ) {
|
||||
mappingColumn.addCheckConstraint( constraint );
|
||||
}
|
||||
mappingColumn.setOptions( options );
|
||||
|
||||
// if ( isNotEmpty( comment ) ) {
|
||||
// mappingColumn.setComment( comment );
|
||||
// }
|
||||
|
@ -313,6 +317,7 @@ public class AnnotatedColumn {
|
|||
mappingColumn.addCheckConstraint( constraint );
|
||||
}
|
||||
mappingColumn.setDefaultValue( defaultValue );
|
||||
mappingColumn.setOptions( options );
|
||||
|
||||
if ( writeExpression != null ) {
|
||||
final int numberOfJdbcParams = StringHelper.count( writeExpression, '?' );
|
||||
|
@ -806,6 +811,7 @@ public class AnnotatedColumn {
|
|||
annotatedColumn.applyColumnDefault( inferredData, numberOfColumns );
|
||||
annotatedColumn.applyGeneratedAs( inferredData, numberOfColumns );
|
||||
annotatedColumn.applyColumnCheckConstraint( column );
|
||||
annotatedColumn.applyColumnOptions( column );
|
||||
annotatedColumn.applyCheckConstraint( inferredData, numberOfColumns );
|
||||
annotatedColumn.extractDataFromPropertyData( propertyHolder, inferredData );
|
||||
annotatedColumn.bind();
|
||||
|
@ -1052,4 +1058,13 @@ public class AnnotatedColumn {
|
|||
MetadataBuildingContext getBuildingContext() {
|
||||
return getParent().getBuildingContext();
|
||||
}
|
||||
|
||||
private void applyColumnOptions(AnnotationUsage<jakarta.persistence.Column> column) {
|
||||
options = column.findAttributeValue( "options" );
|
||||
}
|
||||
|
||||
void setOptions(String options){
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -75,6 +75,7 @@ public class AnnotatedDiscriminatorColumn extends AnnotatedColumn {
|
|||
column.setLogicalColumnName( discriminatorColumn.getString( "name" ) );
|
||||
}
|
||||
column.setNullable( false );
|
||||
column.setOptions( discriminatorColumn.getString( "options" ) );
|
||||
}
|
||||
else {
|
||||
discriminatorType = DiscriminatorType.STRING;
|
||||
|
|
|
@ -196,6 +196,7 @@ public class AnnotatedJoinColumn extends AnnotatedColumn {
|
|||
setUpdatable( joinColumn.getBoolean( "updatable" ) );
|
||||
setReferencedColumn( joinColumn.getString( "referencedColumnName" ) );
|
||||
applyColumnCheckConstraint( joinColumn );
|
||||
setOptions( joinColumn.getString( "options" ) );
|
||||
|
||||
final String table = joinColumn.getString( "table" );
|
||||
if ( table.isEmpty() ) {
|
||||
|
@ -237,15 +238,18 @@ public class AnnotatedJoinColumn extends AnnotatedColumn {
|
|||
final String columnName;
|
||||
final String columnDefinition;
|
||||
final String referencedColumnName;
|
||||
final String options;
|
||||
if ( primaryKeyJoinColumn != null ) {
|
||||
columnName = primaryKeyJoinColumn.getString( "name" );
|
||||
columnDefinition = primaryKeyJoinColumn.getString( "columnDefinition" );
|
||||
referencedColumnName = primaryKeyJoinColumn.getString( "referencedColumnName" );
|
||||
options = primaryKeyJoinColumn.getString( "options" );
|
||||
}
|
||||
else {
|
||||
columnName = joinColumn.getString( "name" );
|
||||
columnDefinition = joinColumn.getString( "columnDefinition" );
|
||||
referencedColumnName = joinColumn.getString( "referencedColumnName" );
|
||||
options = joinColumn.getString( "options" );
|
||||
}
|
||||
|
||||
final ObjectNameNormalizer normalizer = context.getObjectNameNormalizer();
|
||||
|
@ -261,6 +265,7 @@ public class AnnotatedJoinColumn extends AnnotatedColumn {
|
|||
// column.setPropertyHolder(propertyHolder);
|
||||
// column.setJoins(joins);
|
||||
// column.setContext( context );
|
||||
column.setOptions( options );
|
||||
column.setImplicit( false );
|
||||
column.setNullable( false );
|
||||
column.setParent( parent );
|
||||
|
|
|
@ -647,12 +647,10 @@ public abstract class CollectionBinder {
|
|||
}
|
||||
final List<AnnotationUsage<MapKeyJoinColumn>> mapKeyJoinColumns = property.getAnnotationUsage( MapKeyJoinColumns.class ).getList( "value" );
|
||||
final List<AnnotationUsage<JoinColumn>> joinKeyColumns = CollectionHelper.arrayList( mapKeyJoinColumns.size() );
|
||||
int index = 0;
|
||||
for ( AnnotationUsage<MapKeyJoinColumn> mapKeyJoinColumn : mapKeyJoinColumns ) {
|
||||
final MutableAnnotationUsage<JoinColumn> joinColumn
|
||||
= MapKeyJoinColumnDelegator.fromMapKeyJoinColumn( mapKeyJoinColumn, property, context );
|
||||
joinKeyColumns.add( joinColumn );
|
||||
index++;
|
||||
}
|
||||
return joinKeyColumns;
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
*/
|
||||
package org.hibernate.boot.model.internal;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -25,10 +24,8 @@ import org.hibernate.models.spi.MemberDetails;
|
|||
import org.hibernate.models.spi.MutableAnnotationUsage;
|
||||
import org.hibernate.models.spi.SourceModelBuildingContext;
|
||||
|
||||
import jakarta.persistence.CheckConstraint;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.ElementCollection;
|
||||
import jakarta.persistence.ForeignKey;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.JoinColumns;
|
||||
import jakarta.persistence.JoinTable;
|
||||
|
@ -361,77 +358,4 @@ class ColumnsBuilder {
|
|||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("ClassExplicitlyAnnotation")
|
||||
private static final class JoinColumnAdapter implements JoinColumn {
|
||||
private final PrimaryKeyJoinColumn column;
|
||||
|
||||
public JoinColumnAdapter(PrimaryKeyJoinColumn column) {
|
||||
this.column = column;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return column.name();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String referencedColumnName() {
|
||||
return column.referencedColumnName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean unique() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean nullable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean insertable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updatable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String columnDefinition() {
|
||||
return column.columnDefinition();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String table() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String options() {
|
||||
return column.options();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String comment() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public ForeignKey foreignKey() {
|
||||
return column.foreignKey();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CheckConstraint[] check() {
|
||||
return new CheckConstraint[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends Annotation> annotationType() {
|
||||
return JoinColumn.class;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -114,6 +114,7 @@ public class IndexColumn extends AnnotatedColumn {
|
|||
// column.setJoins( secondaryTables );
|
||||
column.setInsertable( orderColumn.getBoolean( "insertable" ) );
|
||||
column.setUpdatable( orderColumn.getBoolean( "updatable" ) );
|
||||
column.setOptions( orderColumn.getString( "options" ) );
|
||||
// column.setContext( context );
|
||||
// column.setPropertyHolder( propertyHolder );
|
||||
createParent( propertyHolder, secondaryTables, column, context );
|
||||
|
|
|
@ -592,6 +592,10 @@ public class ManagedTypeProcessor {
|
|||
xmlDocumentContext
|
||||
);
|
||||
|
||||
XmlAnnotationHelper.applyPrimaryKeyJoinColumns(
|
||||
jaxbEntity, classDetails, xmlDocumentContext
|
||||
);
|
||||
|
||||
renderClass( classDetails, xmlDocumentContext );
|
||||
}
|
||||
|
||||
|
|
|
@ -52,6 +52,7 @@ import org.hibernate.boot.jaxb.mapping.spi.JaxbDiscriminatorColumnImpl;
|
|||
import org.hibernate.boot.jaxb.mapping.spi.JaxbDiscriminatorFormulaImpl;
|
||||
import org.hibernate.boot.jaxb.mapping.spi.JaxbElementCollectionImpl;
|
||||
import org.hibernate.boot.jaxb.mapping.spi.JaxbEntity;
|
||||
import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityImpl;
|
||||
import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityListenerContainerImpl;
|
||||
import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityOrMappedSuperclass;
|
||||
import org.hibernate.boot.jaxb.mapping.spi.JaxbGeneratedValueImpl;
|
||||
|
@ -66,6 +67,7 @@ import org.hibernate.boot.jaxb.mapping.spi.JaxbNationalizedImpl;
|
|||
import org.hibernate.boot.jaxb.mapping.spi.JaxbNaturalId;
|
||||
import org.hibernate.boot.jaxb.mapping.spi.JaxbNotFoundCapable;
|
||||
import org.hibernate.boot.jaxb.mapping.spi.JaxbPluralAttribute;
|
||||
import org.hibernate.boot.jaxb.mapping.spi.JaxbPrimaryKeyJoinColumnImpl;
|
||||
import org.hibernate.boot.jaxb.mapping.spi.JaxbSchemaAware;
|
||||
import org.hibernate.boot.jaxb.mapping.spi.JaxbSecondaryTableImpl;
|
||||
import org.hibernate.boot.jaxb.mapping.spi.JaxbSequenceGeneratorImpl;
|
||||
|
@ -123,6 +125,7 @@ import jakarta.persistence.GeneratedValue;
|
|||
import jakarta.persistence.IdClass;
|
||||
import jakarta.persistence.Index;
|
||||
import jakarta.persistence.Inheritance;
|
||||
import jakarta.persistence.PrimaryKeyJoinColumns;
|
||||
import jakarta.persistence.SecondaryTable;
|
||||
import jakarta.persistence.SecondaryTables;
|
||||
import jakarta.persistence.SequenceGenerator;
|
||||
|
@ -1539,4 +1542,30 @@ public class XmlAnnotationHelper {
|
|||
values.add( tableAnn );
|
||||
}
|
||||
}
|
||||
|
||||
public static void applyPrimaryKeyJoinColumns(
|
||||
JaxbEntityImpl jaxbEntity,
|
||||
MutableClassDetails classDetails,
|
||||
XmlDocumentContext xmlDocumentContext) {
|
||||
List<JaxbPrimaryKeyJoinColumnImpl> primaryKeyJoinColumns = jaxbEntity.getPrimaryKeyJoinColumns();
|
||||
if ( CollectionHelper.isEmpty( primaryKeyJoinColumns ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
final SourceModelBuildingContext modelBuildingContext = xmlDocumentContext.getModelBuildingContext();
|
||||
final MutableAnnotationUsage<PrimaryKeyJoinColumns> primaryKeyJoinColumnsAnnotationUsage = classDetails.replaceAnnotationUsage(
|
||||
JpaAnnotations.PRIMARY_KEY_JOIN_COLUMN,
|
||||
JpaAnnotations.PRIMARY_KEY_JOIN_COLUMNS,
|
||||
modelBuildingContext
|
||||
);
|
||||
|
||||
final ArrayList<Object> primaryKeyJoinColumnList = arrayList( primaryKeyJoinColumns.size() );
|
||||
primaryKeyJoinColumnsAnnotationUsage.setAttributeValue( "value", primaryKeyJoinColumnList );
|
||||
|
||||
for ( JaxbPrimaryKeyJoinColumnImpl primaryKeyJoinColumn : primaryKeyJoinColumns ) {
|
||||
primaryKeyJoinColumnList.add(
|
||||
JoinColumnProcessing.createPrimaryKeyJoinColumnUsage( primaryKeyJoinColumn, xmlDocumentContext )
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -194,28 +194,10 @@ public class JoinColumnProcessing {
|
|||
|
||||
final List<MutableAnnotationUsage<PrimaryKeyJoinColumn>> columnUsages = CollectionHelper.arrayList( jaxbJoinColumns.size() );
|
||||
|
||||
jaxbJoinColumns.forEach( (jaxbJoinColumn) -> {
|
||||
final MutableAnnotationUsage<PrimaryKeyJoinColumn> columnUsage =
|
||||
JpaAnnotations.PRIMARY_KEY_JOIN_COLUMN.createUsage( xmlDocumentContext.getModelBuildingContext() );
|
||||
columnUsages.add( columnUsage );
|
||||
|
||||
ColumnProcessing.applyColumnDetails(
|
||||
jaxbJoinColumn,
|
||||
(MutableAnnotationUsage<? extends Annotation>) columnUsage,
|
||||
xmlDocumentContext
|
||||
);
|
||||
XmlAnnotationHelper.applyOptionalAttribute(
|
||||
columnUsage,
|
||||
"referencedColumnName",
|
||||
((JaxbColumnJoined) jaxbJoinColumn).getReferencedColumnName()
|
||||
);
|
||||
|
||||
ForeignKeyProcessing.applyForeignKey(
|
||||
( (JaxbColumnJoined) jaxbJoinColumn ).getForeignKey(),
|
||||
(MutableAnnotationUsage<? extends Annotation>) columnUsage,
|
||||
xmlDocumentContext
|
||||
);
|
||||
} );
|
||||
jaxbJoinColumns.forEach(
|
||||
(jaxbJoinColumn) ->
|
||||
columnUsages.add( createPrimaryKeyJoinColumnUsage( jaxbJoinColumn, xmlDocumentContext ) )
|
||||
);
|
||||
|
||||
tableAnn.setAttributeValue(
|
||||
"pkJoinColumns",
|
||||
|
@ -223,4 +205,30 @@ public class JoinColumnProcessing {
|
|||
);
|
||||
}
|
||||
|
||||
public static MutableAnnotationUsage<PrimaryKeyJoinColumn> createPrimaryKeyJoinColumnUsage(
|
||||
JaxbPrimaryKeyJoinColumnImpl jaxbJoinColumn,
|
||||
XmlDocumentContext xmlDocumentContext) {
|
||||
final MutableAnnotationUsage<PrimaryKeyJoinColumn> columnUsage =
|
||||
JpaAnnotations.PRIMARY_KEY_JOIN_COLUMN.createUsage( xmlDocumentContext.getModelBuildingContext() );
|
||||
|
||||
ColumnProcessing.applyColumnDetails(
|
||||
jaxbJoinColumn,
|
||||
(MutableAnnotationUsage<? extends Annotation>) columnUsage,
|
||||
xmlDocumentContext
|
||||
);
|
||||
|
||||
XmlAnnotationHelper.applyOptionalAttribute(
|
||||
columnUsage,
|
||||
"referencedColumnName",
|
||||
((JaxbColumnJoined) jaxbJoinColumn ).getReferencedColumnName()
|
||||
);
|
||||
|
||||
ForeignKeyProcessing.applyForeignKey(
|
||||
( (JaxbColumnJoined) jaxbJoinColumn ).getForeignKey(),
|
||||
(MutableAnnotationUsage<? extends Annotation>) columnUsage,
|
||||
xmlDocumentContext
|
||||
);
|
||||
return columnUsage;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -80,6 +80,7 @@ public class Column implements Selectable, Serializable, Cloneable, ColumnTypeIn
|
|||
private Size columnSize;
|
||||
private String collation;
|
||||
private java.util.List<CheckConstraint> checkConstraints = new ArrayList<>();
|
||||
private String options;
|
||||
|
||||
public Column() {
|
||||
}
|
||||
|
@ -788,6 +789,14 @@ public class Column implements Selectable, Serializable, Cloneable, ColumnTypeIn
|
|||
return quoted ? name : name.toLowerCase( Locale.ROOT );
|
||||
}
|
||||
|
||||
public String getOptions() {
|
||||
return options;
|
||||
}
|
||||
|
||||
public void setOptions(String options) {
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shallow copy, the value is not copied
|
||||
*/
|
||||
|
@ -817,6 +826,7 @@ public class Column implements Selectable, Serializable, Cloneable, ColumnTypeIn
|
|||
copy.customWrite = customWrite;
|
||||
// copy.specializedTypeDeclaration = specializedTypeDeclaration;
|
||||
copy.columnSize = columnSize;
|
||||
copy.options = options;
|
||||
return copy;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import org.hibernate.boot.Metadata;
|
|||
import org.hibernate.boot.model.relational.SqlStringGenerationContext;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.engine.jdbc.Size;
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.mapping.CheckConstraint;
|
||||
import org.hibernate.mapping.Column;
|
||||
import org.hibernate.mapping.Constraint;
|
||||
|
@ -111,6 +112,14 @@ class ColumnDefinitions {
|
|||
appendColumnDefinition( statement, column, metadata, dialect );
|
||||
appendComment( statement, column, dialect );
|
||||
appendConstraints( statement, column, table, dialect, context );
|
||||
appendOptions(statement, column, dialect);
|
||||
}
|
||||
|
||||
private static void appendOptions(StringBuilder statement, Column column, Dialect dialect) {
|
||||
final String options = column.getOptions();
|
||||
if ( StringHelper.isNotEmpty( options ) ) {
|
||||
statement.append( " " ).append( options );
|
||||
}
|
||||
}
|
||||
|
||||
private static void appendConstraints(
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
package org.hibernate.orm.test.schemaupdate.columnoptions;
|
||||
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Inheritance;
|
||||
import jakarta.persistence.InheritanceType;
|
||||
import jakarta.persistence.PrimaryKeyJoinColumn;
|
||||
import jakarta.persistence.PrimaryKeyJoinColumns;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
@Entity
|
||||
@Table(name = "ANOTHER_TEST_ENTITY")
|
||||
@PrimaryKeyJoinColumns(
|
||||
value = @PrimaryKeyJoinColumn(name = "joined_fk", options = ColumnOptionsTest.PRIMARY_KEY_JOIN_COLUMN_OPTIONS)
|
||||
)
|
||||
public class AnotherTestEntity extends TestEntity {
|
||||
|
||||
}
|
|
@ -0,0 +1,333 @@
|
|||
package org.hibernate.orm.test.schemaupdate.columnoptions;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.hibernate.boot.MetadataSources;
|
||||
import org.hibernate.boot.registry.StandardServiceRegistry;
|
||||
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
||||
import org.hibernate.boot.spi.MetadataImplementor;
|
||||
import org.hibernate.tool.hbm2ddl.SchemaExport;
|
||||
import org.hibernate.tool.schema.TargetType;
|
||||
|
||||
import org.hibernate.testing.orm.junit.BaseUnitTest;
|
||||
import org.hibernate.testing.orm.junit.JiraKey;
|
||||
import org.hibernate.testing.util.ServiceRegistryUtil;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
@BaseUnitTest
|
||||
@JiraKey("HHH-18057")
|
||||
public class ColumnOptionsTest {
|
||||
static final String COLUMN_NAME = "NAME";
|
||||
static final String COLUMN_OPTIONS = "option_1";
|
||||
|
||||
static final String DISCRIMINATOR_COLUMN_NAME = "DISC_COLUMN";
|
||||
static final String DISCRIMINATOR_COLUMN_OPTIONS = "option_2";
|
||||
|
||||
static final String PRIMARY_KEY_JOIN_COLUMN_NAME = "PRIMARY_KEY_COLUMN";
|
||||
static final String PRIMARY_KEY_JOIN_COLUMN_OPTIONS = "option_3";
|
||||
|
||||
static final String JOIN_COLUMN_NAME = "JOIN_COLUMN";
|
||||
static final String JOIN_COLUMN_OPTIONS = "option_4";
|
||||
|
||||
static final String ELEMENT_COLLECTION_MAP_KEY_COLUMN_NAME = "MAP_KEY_COLUMN";
|
||||
static final String ELEMENT_COLLECTION_MAP_KEY_COLUMN_OPTIONS = "option_5";
|
||||
|
||||
static final String ELEMENT_COLLECTION_MAP_KEY_JOIN_COLUMN_NAME = "MAP_KEY_JOIN_COLUMN";
|
||||
static final String ELEMENT_COLLECTION_MAP_KEY_JOIN_COLUMN_OPTIONS = "option_6";
|
||||
|
||||
static final String ONE_TO_MANY_MAP_KEY_COLUMN_NAME = "MAP_KEY_COLUMN_2";
|
||||
static final String ONE_TO_MANY_MAP_KEY_COLUMN_OPTIONS = "option_7";
|
||||
|
||||
static final String ONE_TO_MANY_MAP_KEY_JOIN_COLUMN_NAME = "MAP_KEY_JOIN_COLUMN_2";
|
||||
static final String ONE_TO_MANY_MAP_KEY_JOIN_COLUMN_OPTIONS = "option_8";
|
||||
|
||||
static final String MANY_TO_MANY_MAP_KEY_COLUMN_NAME = "MAP_KEY_COLUMN_3";
|
||||
static final String MANY_TO_MANY_MAP_KEY_COLUMN_OPTIONS = "option_9";
|
||||
|
||||
static final String MANY_TO_MANY_MAP_KEY_JOIN_COLUMN_NAME = "MAP_KEY_JOIN_COLUMN_3";
|
||||
static final String MANY_TO_MANY_MAP_KEY_JOIN_COLUMN_OPTIONS = "option__10";
|
||||
|
||||
static final String ORDER_COLUMN_NAME = "ORDER_COLUMN";
|
||||
static final String ORDER_COLUMN_OPTIONS = "option__11";
|
||||
|
||||
private File output;
|
||||
private StandardServiceRegistry ssr;
|
||||
private MetadataImplementor metadata;
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() throws IOException {
|
||||
output = File.createTempFile( "update_script", ".sql" );
|
||||
output.deleteOnExit();
|
||||
ssr = ServiceRegistryUtil.serviceRegistry();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void tearsDown() {
|
||||
output.delete();
|
||||
StandardServiceRegistryBuilder.destroy( ssr );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTableCommentAreCreated() throws Exception {
|
||||
createSchema( TestEntity.class, AnotherTestEntity.class );
|
||||
assertTrue(
|
||||
tableCreationStatementContainsOptions( output, COLUMN_NAME, COLUMN_OPTIONS ),
|
||||
"Column " + COLUMN_NAME + " options have not been created "
|
||||
);
|
||||
|
||||
assertTrue(
|
||||
tableCreationStatementContainsOptions(
|
||||
output,
|
||||
DISCRIMINATOR_COLUMN_NAME,
|
||||
DISCRIMINATOR_COLUMN_OPTIONS
|
||||
),
|
||||
"DiscriminatorColumn " + DISCRIMINATOR_COLUMN_NAME + " options have not been created "
|
||||
);
|
||||
|
||||
assertTrue(
|
||||
tableCreationStatementContainsOptions( output, JOIN_COLUMN_NAME, JOIN_COLUMN_OPTIONS ),
|
||||
"JoinColumn " + JOIN_COLUMN_NAME + " options have not been created "
|
||||
);
|
||||
|
||||
assertTrue(
|
||||
tableCreationStatementContainsOptions(
|
||||
output,
|
||||
ELEMENT_COLLECTION_MAP_KEY_COLUMN_NAME,
|
||||
ELEMENT_COLLECTION_MAP_KEY_COLUMN_OPTIONS
|
||||
),
|
||||
"ElementCollection MapKeyColumn " + ELEMENT_COLLECTION_MAP_KEY_COLUMN_NAME + " options have not been created "
|
||||
);
|
||||
|
||||
assertTrue(
|
||||
tableCreationStatementContainsOptions(
|
||||
output,
|
||||
ONE_TO_MANY_MAP_KEY_COLUMN_NAME,
|
||||
ONE_TO_MANY_MAP_KEY_COLUMN_OPTIONS
|
||||
),
|
||||
"OneToMany MapKeyColumn " + ONE_TO_MANY_MAP_KEY_COLUMN_NAME + " options have not been created "
|
||||
);
|
||||
|
||||
assertTrue(
|
||||
tableCreationStatementContainsOptions(
|
||||
output,
|
||||
MANY_TO_MANY_MAP_KEY_COLUMN_NAME,
|
||||
MANY_TO_MANY_MAP_KEY_COLUMN_OPTIONS
|
||||
),
|
||||
"ManyToMany MapKeyColumn " + MANY_TO_MANY_MAP_KEY_COLUMN_NAME + " options have not been created "
|
||||
);
|
||||
|
||||
assertTrue(
|
||||
tableCreationStatementContainsOptions(
|
||||
output,
|
||||
ONE_TO_MANY_MAP_KEY_COLUMN_NAME,
|
||||
ONE_TO_MANY_MAP_KEY_COLUMN_OPTIONS
|
||||
),
|
||||
"OneToMany MapKeyColumn " + ONE_TO_MANY_MAP_KEY_COLUMN_NAME + " options have not been created "
|
||||
);
|
||||
|
||||
assertTrue(
|
||||
tableCreationStatementContainsOptions(
|
||||
output,
|
||||
PRIMARY_KEY_JOIN_COLUMN_NAME,
|
||||
PRIMARY_KEY_JOIN_COLUMN_OPTIONS
|
||||
),
|
||||
"PrimaryKeyJoinColumn " + PRIMARY_KEY_JOIN_COLUMN_NAME + " options have not been created "
|
||||
);
|
||||
|
||||
assertTrue(
|
||||
tableCreationStatementContainsOptions(
|
||||
output,
|
||||
ELEMENT_COLLECTION_MAP_KEY_JOIN_COLUMN_NAME,
|
||||
ELEMENT_COLLECTION_MAP_KEY_JOIN_COLUMN_OPTIONS
|
||||
),
|
||||
"ElementCollection MapKeyJoinColumn " + ELEMENT_COLLECTION_MAP_KEY_JOIN_COLUMN_NAME + " options have not been created "
|
||||
);
|
||||
|
||||
assertTrue(
|
||||
tableCreationStatementContainsOptions(
|
||||
output,
|
||||
ONE_TO_MANY_MAP_KEY_JOIN_COLUMN_NAME,
|
||||
ONE_TO_MANY_MAP_KEY_JOIN_COLUMN_OPTIONS
|
||||
),
|
||||
"OneToMany MapKeyJoinColumn " + ONE_TO_MANY_MAP_KEY_JOIN_COLUMN_NAME + " options have not been created "
|
||||
);
|
||||
|
||||
assertTrue(
|
||||
tableCreationStatementContainsOptions(
|
||||
output,
|
||||
MANY_TO_MANY_MAP_KEY_JOIN_COLUMN_NAME,
|
||||
MANY_TO_MANY_MAP_KEY_JOIN_COLUMN_OPTIONS
|
||||
),
|
||||
"ManyToMany MapKeyJoinColumn " + MANY_TO_MANY_MAP_KEY_JOIN_COLUMN_OPTIONS + " options have not been created "
|
||||
);
|
||||
|
||||
assertTrue(
|
||||
tableCreationStatementContainsOptions(
|
||||
output,
|
||||
ORDER_COLUMN_NAME,
|
||||
ORDER_COLUMN_OPTIONS
|
||||
),
|
||||
"OrderColumn " + ORDER_COLUMN_NAME + " options have not been created "
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testXmlMappingTableCommentAreCreated() throws Exception {
|
||||
createSchema( "org/hibernate/orm/test/schemaupdate/columnoptions/TestEntity.xml" );
|
||||
assertTrue(
|
||||
tableCreationStatementContainsOptions( output, COLUMN_NAME, COLUMN_OPTIONS ),
|
||||
"Column " + COLUMN_NAME + " options have not been created "
|
||||
);
|
||||
|
||||
assertTrue(
|
||||
tableCreationStatementContainsOptions(
|
||||
output,
|
||||
DISCRIMINATOR_COLUMN_NAME,
|
||||
DISCRIMINATOR_COLUMN_OPTIONS
|
||||
),
|
||||
"DiscriminatorColumn " + DISCRIMINATOR_COLUMN_NAME + " options have not been created "
|
||||
);
|
||||
|
||||
assertTrue(
|
||||
tableCreationStatementContainsOptions( output, JOIN_COLUMN_NAME, JOIN_COLUMN_OPTIONS ),
|
||||
"JoinColumn " + JOIN_COLUMN_NAME + " options have not been created "
|
||||
);
|
||||
|
||||
assertTrue(
|
||||
tableCreationStatementContainsOptions(
|
||||
output,
|
||||
ELEMENT_COLLECTION_MAP_KEY_COLUMN_NAME,
|
||||
ELEMENT_COLLECTION_MAP_KEY_COLUMN_OPTIONS
|
||||
),
|
||||
"ElementCollection MapKeyColumn " + ELEMENT_COLLECTION_MAP_KEY_COLUMN_NAME + " options have not been created "
|
||||
);
|
||||
|
||||
assertTrue(
|
||||
tableCreationStatementContainsOptions(
|
||||
output,
|
||||
ONE_TO_MANY_MAP_KEY_COLUMN_NAME,
|
||||
ONE_TO_MANY_MAP_KEY_COLUMN_OPTIONS
|
||||
),
|
||||
"OneToMany MapKeyColumn " + ONE_TO_MANY_MAP_KEY_COLUMN_NAME + " options have not been created "
|
||||
);
|
||||
|
||||
assertTrue(
|
||||
tableCreationStatementContainsOptions(
|
||||
output,
|
||||
MANY_TO_MANY_MAP_KEY_COLUMN_NAME,
|
||||
MANY_TO_MANY_MAP_KEY_COLUMN_OPTIONS
|
||||
),
|
||||
"ManyToMany MapKeyColumn " + MANY_TO_MANY_MAP_KEY_COLUMN_NAME + " options have not been created "
|
||||
);
|
||||
|
||||
assertTrue(
|
||||
tableCreationStatementContainsOptions(
|
||||
output,
|
||||
ONE_TO_MANY_MAP_KEY_COLUMN_NAME,
|
||||
ONE_TO_MANY_MAP_KEY_COLUMN_OPTIONS
|
||||
),
|
||||
"OneToMany MapKeyColumn " + ONE_TO_MANY_MAP_KEY_COLUMN_NAME + " options have not been created "
|
||||
);
|
||||
|
||||
assertTrue(
|
||||
tableCreationStatementContainsOptions(
|
||||
output,
|
||||
PRIMARY_KEY_JOIN_COLUMN_NAME,
|
||||
PRIMARY_KEY_JOIN_COLUMN_OPTIONS
|
||||
),
|
||||
"PrimaryKeyJoinColumn " + PRIMARY_KEY_JOIN_COLUMN_NAME + " options have not been created "
|
||||
);
|
||||
|
||||
assertTrue(
|
||||
tableCreationStatementContainsOptions(
|
||||
output,
|
||||
ELEMENT_COLLECTION_MAP_KEY_JOIN_COLUMN_NAME,
|
||||
ELEMENT_COLLECTION_MAP_KEY_JOIN_COLUMN_OPTIONS
|
||||
),
|
||||
"ElementCollection MapKeyJoinColumn " + ELEMENT_COLLECTION_MAP_KEY_JOIN_COLUMN_NAME + " options have not been created "
|
||||
);
|
||||
|
||||
assertTrue(
|
||||
tableCreationStatementContainsOptions(
|
||||
output,
|
||||
ONE_TO_MANY_MAP_KEY_JOIN_COLUMN_NAME,
|
||||
ONE_TO_MANY_MAP_KEY_JOIN_COLUMN_OPTIONS
|
||||
),
|
||||
"OneToMany MapKeyJoinColumn " + ONE_TO_MANY_MAP_KEY_JOIN_COLUMN_NAME + " options have not been created "
|
||||
);
|
||||
|
||||
assertTrue(
|
||||
tableCreationStatementContainsOptions(
|
||||
output,
|
||||
MANY_TO_MANY_MAP_KEY_JOIN_COLUMN_NAME,
|
||||
MANY_TO_MANY_MAP_KEY_JOIN_COLUMN_OPTIONS
|
||||
),
|
||||
"ManyToMany MapKeyJoinColumn " + MANY_TO_MANY_MAP_KEY_JOIN_COLUMN_OPTIONS + " options have not been created "
|
||||
);
|
||||
|
||||
assertTrue(
|
||||
tableCreationStatementContainsOptions(
|
||||
output,
|
||||
ORDER_COLUMN_NAME,
|
||||
ORDER_COLUMN_OPTIONS
|
||||
),
|
||||
"OrderColumn " + ORDER_COLUMN_NAME + " options have not been created "
|
||||
);
|
||||
}
|
||||
|
||||
private static boolean tableCreationStatementContainsOptions(
|
||||
File output,
|
||||
String columnName,
|
||||
String options) throws Exception {
|
||||
String[] fileContent = new String( Files.readAllBytes( output.toPath() ) ).toLowerCase()
|
||||
.split( System.lineSeparator() );
|
||||
for ( int i = 0; i < fileContent.length; i++ ) {
|
||||
String statement = fileContent[i].toUpperCase( Locale.ROOT );
|
||||
if ( statement.contains( options.toUpperCase( Locale.ROOT ) ) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void createSchema(String... xmlMapping) {
|
||||
final MetadataSources metadataSources = new MetadataSources( ssr );
|
||||
|
||||
for ( String xml : xmlMapping ) {
|
||||
metadataSources.addResource( xml );
|
||||
}
|
||||
metadata = (MetadataImplementor) metadataSources.buildMetadata();
|
||||
metadata.orderColumns( false );
|
||||
metadata.validate();
|
||||
new SchemaExport()
|
||||
.setHaltOnError( true )
|
||||
.setOutputFile( output.getAbsolutePath() )
|
||||
.setFormat( false )
|
||||
.create( EnumSet.of( TargetType.SCRIPT ), metadata );
|
||||
}
|
||||
|
||||
private void createSchema(Class... annotatedClasses) {
|
||||
final MetadataSources metadataSources = new MetadataSources( ssr );
|
||||
|
||||
for ( Class c : annotatedClasses ) {
|
||||
metadataSources.addAnnotatedClass( c );
|
||||
}
|
||||
metadata = (MetadataImplementor) metadataSources.buildMetadata();
|
||||
metadata.orderColumns( false );
|
||||
metadata.validate();
|
||||
new SchemaExport()
|
||||
.setHaltOnError( true )
|
||||
.setOutputFile( output.getAbsolutePath() )
|
||||
.setFormat( false )
|
||||
.createOnly( EnumSet.of( TargetType.SCRIPT ), metadata );
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,166 @@
|
|||
package org.hibernate.orm.test.schemaupdate.columnoptions;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import jakarta.persistence.CollectionTable;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.DiscriminatorColumn;
|
||||
import jakarta.persistence.ElementCollection;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Inheritance;
|
||||
import jakarta.persistence.InheritanceType;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.JoinColumns;
|
||||
import jakarta.persistence.JoinTable;
|
||||
import jakarta.persistence.ManyToMany;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.MapKeyColumn;
|
||||
import jakarta.persistence.MapKeyJoinColumn;
|
||||
import jakarta.persistence.MapKeyTemporal;
|
||||
import jakarta.persistence.OneToMany;
|
||||
import jakarta.persistence.OrderColumn;
|
||||
import jakarta.persistence.Table;
|
||||
import jakarta.persistence.TemporalType;
|
||||
|
||||
@Entity
|
||||
@Table(name = "TEST_ENTITY")
|
||||
@Inheritance(strategy = InheritanceType.JOINED)
|
||||
@DiscriminatorColumn(name = ColumnOptionsTest.DISCRIMINATOR_COLUMN_NAME, options = ColumnOptionsTest.DISCRIMINATOR_COLUMN_OPTIONS)
|
||||
public class TestEntity {
|
||||
@Id
|
||||
private int id;
|
||||
|
||||
@Column(name = ColumnOptionsTest.COLUMN_NAME, options = ColumnOptionsTest.COLUMN_OPTIONS)
|
||||
private String name;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumns(
|
||||
value = @JoinColumn(name = ColumnOptionsTest.JOIN_COLUMN_NAME, options = ColumnOptionsTest.JOIN_COLUMN_OPTIONS)
|
||||
|
||||
)
|
||||
private TestEntity testEntity;
|
||||
|
||||
@MapKeyTemporal(TemporalType.DATE)
|
||||
@ElementCollection
|
||||
@MapKeyColumn(name = ColumnOptionsTest.ELEMENT_COLLECTION_MAP_KEY_COLUMN_NAME, options = ColumnOptionsTest.ELEMENT_COLLECTION_MAP_KEY_COLUMN_OPTIONS)
|
||||
private Map<Date, Integer> colorPerDate = new HashMap<>();
|
||||
|
||||
@OneToMany
|
||||
@MapKeyColumn(name = ColumnOptionsTest.ONE_TO_MANY_MAP_KEY_COLUMN_NAME, options = ColumnOptionsTest.ONE_TO_MANY_MAP_KEY_COLUMN_OPTIONS)
|
||||
private Map<Date, TestEntity> testEntityMap = new HashMap<>();
|
||||
|
||||
@ManyToMany
|
||||
@MapKeyColumn(name = ColumnOptionsTest.MANY_TO_MANY_MAP_KEY_COLUMN_NAME, options = ColumnOptionsTest.MANY_TO_MANY_MAP_KEY_COLUMN_OPTIONS)
|
||||
private Map<Date, TestEntity> testEntityMap2 = new HashMap<>();
|
||||
|
||||
@ElementCollection
|
||||
@CollectionTable(
|
||||
name = "ELEMENT_COLLECTION_TABLE")
|
||||
@MapKeyJoinColumn(name = ColumnOptionsTest.ELEMENT_COLLECTION_MAP_KEY_JOIN_COLUMN_NAME, insertable = false, options = ColumnOptionsTest.ELEMENT_COLLECTION_MAP_KEY_JOIN_COLUMN_OPTIONS)
|
||||
private Map<AnotherTestEntity, String> stringMap = new HashMap<>();
|
||||
|
||||
@OneToMany
|
||||
@JoinTable(name = "TEST_ENTITY_3")
|
||||
@MapKeyJoinColumn(name = ColumnOptionsTest.ONE_TO_MANY_MAP_KEY_JOIN_COLUMN_NAME, options = ColumnOptionsTest.ONE_TO_MANY_MAP_KEY_JOIN_COLUMN_OPTIONS)
|
||||
private Map<TestEntity, TestEntity> testEntityMap3 = new HashMap<>();
|
||||
|
||||
@ManyToMany
|
||||
@JoinTable(name = "TEST_ENTITY_4")
|
||||
@MapKeyJoinColumn(name = ColumnOptionsTest.MANY_TO_MANY_MAP_KEY_JOIN_COLUMN_NAME, options = ColumnOptionsTest.MANY_TO_MANY_MAP_KEY_JOIN_COLUMN_OPTIONS)
|
||||
private Map<TestEntity, TestEntity> testEntityMap4 = new HashMap<>();
|
||||
|
||||
@ElementCollection
|
||||
@OrderColumn(name = ColumnOptionsTest.ORDER_COLUMN_NAME, options = ColumnOptionsTest.ORDER_COLUMN_OPTIONS)
|
||||
int[] theNumbers;
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public TestEntity getTestEntity() {
|
||||
return testEntity;
|
||||
}
|
||||
|
||||
public void setTestEntity(TestEntity testEntity) {
|
||||
this.testEntity = testEntity;
|
||||
}
|
||||
|
||||
public Map<Date, Integer> getColorPerDate() {
|
||||
return colorPerDate;
|
||||
}
|
||||
|
||||
public void setColorPerDate(Map<Date, Integer> colorPerDate) {
|
||||
this.colorPerDate = colorPerDate;
|
||||
}
|
||||
|
||||
public Map<Date, TestEntity> getTestEntityMap() {
|
||||
return testEntityMap;
|
||||
}
|
||||
|
||||
public void setTestEntityMap(Map<Date, TestEntity> testEntityMap) {
|
||||
this.testEntityMap = testEntityMap;
|
||||
}
|
||||
|
||||
public Map<Date, TestEntity> getTestEntityMap2() {
|
||||
return testEntityMap2;
|
||||
}
|
||||
|
||||
public void setTestEntityMap2(Map<Date, TestEntity> testEntityMap2) {
|
||||
this.testEntityMap2 = testEntityMap2;
|
||||
}
|
||||
|
||||
public Map<AnotherTestEntity, String> getStringMap() {
|
||||
return stringMap;
|
||||
}
|
||||
|
||||
public void setStringMap(Map<AnotherTestEntity, String> stringMap) {
|
||||
this.stringMap = stringMap;
|
||||
}
|
||||
|
||||
public Map<TestEntity, TestEntity> getTestEntityMap3() {
|
||||
return testEntityMap3;
|
||||
}
|
||||
|
||||
public void setTestEntityMap3(Map<TestEntity, TestEntity> testEntityMap3) {
|
||||
this.testEntityMap3 = testEntityMap3;
|
||||
}
|
||||
|
||||
public Map<TestEntity, TestEntity> getTestEntityMap4() {
|
||||
return testEntityMap4;
|
||||
}
|
||||
|
||||
public void setTestEntityMap4(Map<TestEntity, TestEntity> testEntityMap4) {
|
||||
this.testEntityMap4 = testEntityMap4;
|
||||
}
|
||||
|
||||
public int[] getTheNumbers() {
|
||||
return theNumbers;
|
||||
}
|
||||
|
||||
public void setTheNumbers(int[] theNumbers) {
|
||||
this.theNumbers = theNumbers;
|
||||
}
|
||||
|
||||
// public AnotherTestEntity getAnotherTestEntity() {
|
||||
// return anotherTestEntity;
|
||||
// }
|
||||
//
|
||||
// public void setAnotherTestEntity(AnotherTestEntity anotherTestEntity) {
|
||||
// this.anotherTestEntity = anotherTestEntity;
|
||||
// }
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Hibernate, Relational Persistence for Idiomatic Java
|
||||
~
|
||||
~ License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
~ See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
-->
|
||||
<entity-mappings xmlns="http://www.hibernate.org/xsd/orm/mapping" version="3.2">
|
||||
<package>org.hibernate.orm.test.schemaupdate.columnoptions</package>
|
||||
<entity class="TestEntity" metadata-complete="true">
|
||||
<table name="PRIMARY_TABLE" options="option_1"/>
|
||||
<inheritance strategy="JOINED"/>
|
||||
<discriminator-column name="DISC_COLUMN" options="option_2"/>
|
||||
<attributes>
|
||||
<id name="id"/>
|
||||
<basic name="name">
|
||||
<column name="NAME_COLUMN" options="option_1"/>
|
||||
</basic>
|
||||
<many-to-one name="testEntity">
|
||||
<join-column name="JOIN_COLUMN" options="option_4"/>
|
||||
</many-to-one>
|
||||
<one-to-many name="testEntityMap">
|
||||
<map-key-column name="MAP_KEY_COLUMN_2" options="option_7"/>
|
||||
</one-to-many>
|
||||
<one-to-many name="testEntityMap3">
|
||||
<map-key-join-column name="MAP_KEY_JOIN_COLUMN_2" options="option_8"/>
|
||||
<join-table name="TEST_ENTITY_3"/>
|
||||
</one-to-many>
|
||||
<many-to-many name="testEntityMap2">
|
||||
<map-key-column name="MAP_KEY_COLUMN_3" options="option_9"/>
|
||||
</many-to-many>
|
||||
<many-to-many name="testEntityMap4">
|
||||
<map-key-join-column name="MAP_KEY_JOIN_COLUMN_3" options="option__10"/>
|
||||
<join-table name="TEST_ENTITY_4"/>
|
||||
</many-to-many>
|
||||
<element-collection name="colorPerDate">
|
||||
<map-key-temporal>DATE</map-key-temporal>
|
||||
<map-key-column name="MAP_KEY_COLUMN" options="option_5"/>
|
||||
</element-collection>
|
||||
<element-collection name="stringMap">
|
||||
<map-key-join-column name="MAP_KEY_JOIN_COLUMN" options="option_6"/>
|
||||
<collection-table name="ELEMENT_COLLECTION_TABLE"/>
|
||||
</element-collection>
|
||||
<element-collection name="theNumbers">
|
||||
<order-column name="ORDER_COLUMN" options="option__11"/>
|
||||
</element-collection>
|
||||
|
||||
</attributes>
|
||||
</entity>
|
||||
<entity class="AnotherTestEntity" metadata-complete="true">
|
||||
<table name="ANOTHER_TEST_ENTITY"/>
|
||||
<primary-key-join-column name="joined_fk" options="option_3"/>
|
||||
</entity>
|
||||
</entity-mappings>
|
Loading…
Reference in New Issue