HHH-18054 Support for JPA 3.2 @CheckConstraint
This commit is contained in:
parent
905e86a04d
commit
ff07248944
|
@ -41,6 +41,8 @@ import org.hibernate.exception.spi.SQLExceptionConversionDelegate;
|
|||
import org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtractor;
|
||||
import org.hibernate.exception.spi.ViolatedConstraintNameExtractor;
|
||||
import org.hibernate.internal.util.JdbcExceptionHelper;
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.mapping.CheckConstraint;
|
||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
|
||||
import org.hibernate.query.sqm.CastType;
|
||||
|
@ -1429,4 +1431,11 @@ public class MySQLLegacyDialect extends Dialect {
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String appendCheckConstraintOptions(CheckConstraint checkConstraint, String sqlCheckConstraint) {
|
||||
if ( StringHelper.isNotEmpty( checkConstraint.getOptions() ) ) {
|
||||
return sqlCheckConstraint + " " + checkConstraint.getOptions();
|
||||
}
|
||||
return sqlCheckConstraint;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -68,6 +68,7 @@ import org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtractor;
|
|||
import org.hibernate.exception.spi.ViolatedConstraintNameExtractor;
|
||||
import org.hibernate.internal.util.JdbcExceptionHelper;
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.mapping.CheckConstraint;
|
||||
import org.hibernate.mapping.UserDefinedType;
|
||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
|
||||
|
@ -1570,4 +1571,12 @@ public class OracleLegacyDialect extends Dialect {
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String appendCheckConstraintOptions(CheckConstraint checkConstraint, String sqlCheckConstraint) {
|
||||
if ( StringHelper.isNotEmpty( checkConstraint.getOptions() ) ) {
|
||||
return sqlCheckConstraint + " " + checkConstraint.getOptions();
|
||||
}
|
||||
return sqlCheckConstraint;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,6 +49,8 @@ import org.hibernate.exception.spi.SQLExceptionConversionDelegate;
|
|||
import org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtractor;
|
||||
import org.hibernate.exception.spi.ViolatedConstraintNameExtractor;
|
||||
import org.hibernate.internal.util.JdbcExceptionHelper;
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.mapping.CheckConstraint;
|
||||
import org.hibernate.mapping.Column;
|
||||
import org.hibernate.query.sqm.CastType;
|
||||
import org.hibernate.query.sqm.FetchClauseType;
|
||||
|
@ -1159,4 +1161,21 @@ public class SQLServerLegacyDialect extends AbstractTransactSQLDialect {
|
|||
public boolean supportsFromClauseInUpdate() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCheckConstraintString(CheckConstraint checkConstraint) {
|
||||
final String constraintName = checkConstraint.getName();
|
||||
return constraintName == null
|
||||
?
|
||||
" check " + getCheckConstraintOptions( checkConstraint ) + "(" + checkConstraint.getConstraint() + ")"
|
||||
:
|
||||
" constraint " + constraintName + " check " + getCheckConstraintOptions( checkConstraint ) + "(" + checkConstraint.getConstraint() + ")";
|
||||
}
|
||||
|
||||
private String getCheckConstraintOptions(CheckConstraint checkConstraint) {
|
||||
if ( StringHelper.isNotEmpty( checkConstraint.getOptions() ) ) {
|
||||
return checkConstraint.getOptions() + " ";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ import org.hibernate.boot.spi.MetadataBuildingContext;
|
|||
import org.hibernate.boot.spi.PropertyData;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||
import org.hibernate.mapping.AggregateColumn;
|
||||
import org.hibernate.mapping.CheckConstraint;
|
||||
import org.hibernate.mapping.Column;
|
||||
|
@ -213,6 +214,10 @@ public class AnnotatedColumn {
|
|||
checkConstraints.add( new CheckConstraint( name, constraint ) );
|
||||
}
|
||||
|
||||
public void addCheckConstraint(String name, String constraint, String options) {
|
||||
checkConstraints.add( new CheckConstraint( name, constraint, options ) );
|
||||
}
|
||||
|
||||
// public String getComment() {
|
||||
// return comment;
|
||||
// }
|
||||
|
@ -800,6 +805,7 @@ public class AnnotatedColumn {
|
|||
annotatedColumn.setParent( parent );
|
||||
annotatedColumn.applyColumnDefault( inferredData, numberOfColumns );
|
||||
annotatedColumn.applyGeneratedAs( inferredData, numberOfColumns );
|
||||
annotatedColumn.applyColumnCheckConstraint( column );
|
||||
annotatedColumn.applyCheckConstraint( inferredData, numberOfColumns );
|
||||
annotatedColumn.extractDataFromPropertyData( propertyHolder, inferredData );
|
||||
annotatedColumn.bind();
|
||||
|
@ -873,7 +879,23 @@ public class AnnotatedColumn {
|
|||
}
|
||||
}
|
||||
|
||||
private void applyCheckConstraint(PropertyData inferredData, int length) {
|
||||
private void applyColumnCheckConstraint(AnnotationUsage<jakarta.persistence.Column> column) {
|
||||
applyCheckConstraints( column.findAttributeValue( "check" ) );
|
||||
}
|
||||
|
||||
void applyCheckConstraints(List<AnnotationUsage<jakarta.persistence.CheckConstraint>> checkConstraintAnnotationUsages) {
|
||||
if ( CollectionHelper.isNotEmpty( checkConstraintAnnotationUsages ) ) {
|
||||
for ( AnnotationUsage<jakarta.persistence.CheckConstraint> checkConstraintAnnotationUsage : checkConstraintAnnotationUsages ) {
|
||||
addCheckConstraint(
|
||||
checkConstraintAnnotationUsage.getString( "name" ),
|
||||
checkConstraintAnnotationUsage.getString( "constraint" ),
|
||||
checkConstraintAnnotationUsage.getString( "options" )
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void applyCheckConstraint(PropertyData inferredData, int length) {
|
||||
final MemberDetails attributeMember = inferredData.getAttributeMember();
|
||||
if ( attributeMember != null ) {
|
||||
// if there are multiple annotations, they're not overrideable
|
||||
|
|
|
@ -195,6 +195,7 @@ public class AnnotatedJoinColumn extends AnnotatedColumn {
|
|||
setInsertable( joinColumn.getBoolean( "insertable" ) );
|
||||
setUpdatable( joinColumn.getBoolean( "updatable" ) );
|
||||
setReferencedColumn( joinColumn.getString( "referencedColumnName" ) );
|
||||
applyColumnCheckConstraint( joinColumn );
|
||||
|
||||
final String table = joinColumn.getString( "table" );
|
||||
if ( table.isEmpty() ) {
|
||||
|
@ -516,4 +517,8 @@ public class AnnotatedJoinColumn extends AnnotatedColumn {
|
|||
public void setParent(AnnotatedJoinColumns parent) {
|
||||
super.setParent( parent );
|
||||
}
|
||||
|
||||
private void applyColumnCheckConstraint(AnnotationUsage<jakarta.persistence.JoinColumn> column) {
|
||||
applyCheckConstraints( column.findAttributeValue( "check" ) );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2584,6 +2584,11 @@ public abstract class CollectionBinder {
|
|||
property.forEachAnnotationUsage( Check.class, (usage) -> {
|
||||
addCheckToCollection( collectionTable, usage );
|
||||
} );
|
||||
property.forEachAnnotationUsage(
|
||||
jakarta.persistence.JoinTable.class,
|
||||
(usage) ->
|
||||
TableBinder.addTableCheck( collectionTable, usage.findAttributeValue( "check" ) )
|
||||
);
|
||||
}
|
||||
|
||||
private static void addCheckToCollection(Table collectionTable, AnnotationUsage<Check> check) {
|
||||
|
|
|
@ -447,7 +447,9 @@ public class EntityBinder {
|
|||
|
||||
final AnnotationUsage<jakarta.persistence.Table> jpaTableUsage = annotatedClass.getAnnotationUsage( jakarta.persistence.Table.class );
|
||||
if ( jpaTableUsage != null ) {
|
||||
TableBinder.addJpaIndexes( persistentClass.getTable(), jpaTableUsage.getList( "indexes" ), context );
|
||||
final Table table = persistentClass.getTable();
|
||||
TableBinder.addJpaIndexes( table, jpaTableUsage.getList( "indexes" ), context );
|
||||
TableBinder.addTableCheck( table, jpaTableUsage.findAttributeValue( "check" ) );
|
||||
}
|
||||
|
||||
final InFlightMetadataCollector.EntityTableXref entityTableXref = context
|
||||
|
@ -2167,7 +2169,7 @@ public class EntityBinder {
|
|||
|
||||
//Used for @*ToMany @JoinTable
|
||||
public Join addJoinTable(AnnotationUsage<JoinTable> joinTable, PropertyHolder holder, boolean noDelayInPkColumnCreation) {
|
||||
return addJoin(
|
||||
final Join join = addJoin(
|
||||
holder,
|
||||
noDelayInPkColumnCreation,
|
||||
false,
|
||||
|
@ -2177,6 +2179,8 @@ public class EntityBinder {
|
|||
joinTable.getList( "joinColumns" ),
|
||||
joinTable.getList( "uniqueConstraints" )
|
||||
);
|
||||
TableBinder.addTableCheck( join.getTable(), joinTable.findAttributeValue( "check" ));
|
||||
return join;
|
||||
}
|
||||
|
||||
public Join addSecondaryTable(AnnotationUsage<SecondaryTable> secondaryTable, PropertyHolder holder, boolean noDelayInPkColumnCreation) {
|
||||
|
@ -2192,6 +2196,7 @@ public class EntityBinder {
|
|||
);
|
||||
final Table table = join.getTable();
|
||||
new IndexBinder( context ).bindIndexes( table, secondaryTable.getList( "indexes" ) );
|
||||
TableBinder.addTableCheck( table, secondaryTable.findAttributeValue( "check" ));
|
||||
return join;
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,8 @@ import org.hibernate.boot.spi.MetadataBuildingContext;
|
|||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
import org.hibernate.mapping.Any;
|
||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||
import org.hibernate.mapping.CheckConstraint;
|
||||
import org.hibernate.mapping.Collection;
|
||||
import org.hibernate.mapping.Column;
|
||||
import org.hibernate.mapping.Component;
|
||||
|
@ -870,6 +872,22 @@ public class TableBinder {
|
|||
new IndexBinder( context ).bindIndexes( table, indexes );
|
||||
}
|
||||
|
||||
static void addTableCheck(
|
||||
Table table,
|
||||
List<AnnotationUsage<jakarta.persistence.CheckConstraint>> checkConstraintAnnotationUsages) {
|
||||
if ( CollectionHelper.isNotEmpty( checkConstraintAnnotationUsages ) ) {
|
||||
for ( AnnotationUsage<jakarta.persistence.CheckConstraint> checkConstraintAnnotationUsage : checkConstraintAnnotationUsages ) {
|
||||
table.addCheck(
|
||||
new CheckConstraint(
|
||||
checkConstraintAnnotationUsage.getString( "name" ),
|
||||
checkConstraintAnnotationUsage.getString( "constraint" ),
|
||||
checkConstraintAnnotationUsage.getString( "options" )
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setDefaultName(
|
||||
String ownerClassName,
|
||||
String ownerEntity,
|
||||
|
|
|
@ -109,6 +109,7 @@ import org.hibernate.internal.util.MathHelper;
|
|||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.internal.util.collections.ArrayHelper;
|
||||
import org.hibernate.loader.ast.spi.MultiKeyLoadSizingStrategy;
|
||||
import org.hibernate.mapping.CheckConstraint;
|
||||
import org.hibernate.mapping.Column;
|
||||
import org.hibernate.mapping.Constraint;
|
||||
import org.hibernate.mapping.ForeignKey;
|
||||
|
@ -5627,4 +5628,30 @@ public abstract class Dialect implements ConversionContext, TypeContributor, Fun
|
|||
return FunctionalDependencyAnalysisSupportImpl.NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a SQL check condition for {@link CheckConstraint}
|
||||
*
|
||||
* @return a SQL expression representing the {@link CheckConstraint}
|
||||
*/
|
||||
public String getCheckConstraintString(CheckConstraint checkConstraint) {
|
||||
final String constraintName = checkConstraint.getName();
|
||||
String constraint = constraintName == null
|
||||
? " check (" + checkConstraint.getConstraint() + ")"
|
||||
: " constraint " + constraintName + " check (" + checkConstraint.getConstraint() + ")";
|
||||
return appendCheckConstraintOptions( checkConstraint, constraint );
|
||||
}
|
||||
|
||||
/**
|
||||
* Append the {@link CheckConstraint} options to SQL check sqlCheckConstraint
|
||||
*
|
||||
* @param checkConstraint an instance of {@link CheckConstraint}
|
||||
* @param sqlCheckConstraint the SQL to append the {@link CheckConstraint} options
|
||||
*
|
||||
* @return a SQL expression
|
||||
*/
|
||||
public String appendCheckConstraintOptions(CheckConstraint checkConstraint, String sqlCheckConstraint) {
|
||||
return sqlCheckConstraint;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -47,6 +47,8 @@ import org.hibernate.exception.spi.SQLExceptionConversionDelegate;
|
|||
import org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtractor;
|
||||
import org.hibernate.exception.spi.ViolatedConstraintNameExtractor;
|
||||
import org.hibernate.internal.util.JdbcExceptionHelper;
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.mapping.CheckConstraint;
|
||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
|
||||
import org.hibernate.query.sqm.CastType;
|
||||
|
@ -1571,4 +1573,12 @@ public class MySQLDialect extends Dialect {
|
|||
public boolean supportsFromClauseInUpdate() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String appendCheckConstraintOptions(CheckConstraint checkConstraint, String sqlCheckConstraint) {
|
||||
if ( StringHelper.isNotEmpty( checkConstraint.getOptions() ) ) {
|
||||
return sqlCheckConstraint + " " + checkConstraint.getOptions();
|
||||
}
|
||||
return sqlCheckConstraint;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,8 +49,10 @@ import org.hibernate.exception.spi.SQLExceptionConversionDelegate;
|
|||
import org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtractor;
|
||||
import org.hibernate.exception.spi.ViolatedConstraintNameExtractor;
|
||||
import org.hibernate.internal.util.JdbcExceptionHelper;
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.internal.util.config.ConfigurationHelper;
|
||||
import org.hibernate.mapping.UserDefinedType;
|
||||
import org.hibernate.mapping.CheckConstraint;
|
||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
|
||||
import org.hibernate.persister.entity.mutation.EntityMutationTarget;
|
||||
|
@ -1692,4 +1694,12 @@ public class OracleDialect extends Dialect {
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String appendCheckConstraintOptions(CheckConstraint checkConstraint, String sqlCheckConstraint) {
|
||||
if ( StringHelper.isNotEmpty( checkConstraint.getOptions() ) ) {
|
||||
return sqlCheckConstraint + " " + checkConstraint.getOptions();
|
||||
}
|
||||
return sqlCheckConstraint;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,6 +55,8 @@ import org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtractor;
|
|||
import org.hibernate.exception.spi.ViolatedConstraintNameExtractor;
|
||||
import org.hibernate.internal.util.JdbcExceptionHelper;
|
||||
import org.hibernate.internal.util.config.ConfigurationHelper;
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.mapping.CheckConstraint;
|
||||
import org.hibernate.mapping.Column;
|
||||
import org.hibernate.persister.entity.mutation.EntityMutationTarget;
|
||||
import org.hibernate.procedure.internal.SQLServerCallableStatementSupport;
|
||||
|
@ -1193,4 +1195,20 @@ public class SQLServerDialect extends AbstractTransactSQLDialect {
|
|||
return SQLServerCallableStatementSupport.INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCheckConstraintString(CheckConstraint checkConstraint) {
|
||||
final String constraintName = checkConstraint.getName();
|
||||
return constraintName == null
|
||||
?
|
||||
" check " + getCheckConstraintOptions( checkConstraint ) + "(" + checkConstraint.getConstraint() + ")"
|
||||
:
|
||||
" constraint " + constraintName + " check " + getCheckConstraintOptions( checkConstraint ) + "(" + checkConstraint.getConstraint() + ")";
|
||||
}
|
||||
|
||||
private String getCheckConstraintOptions(CheckConstraint checkConstraint) {
|
||||
if ( StringHelper.isNotEmpty( checkConstraint.getOptions() ) ) {
|
||||
return checkConstraint.getOptions() + " ";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,8 @@ package org.hibernate.mapping;
|
|||
|
||||
import java.util.Objects;
|
||||
|
||||
import org.hibernate.dialect.Dialect;
|
||||
|
||||
/**
|
||||
* Represents a table or column level {@code check} constraint.
|
||||
*
|
||||
|
@ -16,12 +18,19 @@ import java.util.Objects;
|
|||
public class CheckConstraint {
|
||||
private String name;
|
||||
private String constraint;
|
||||
private String options;
|
||||
|
||||
public CheckConstraint(String name, String constraint) {
|
||||
this.name = name;
|
||||
this.constraint = constraint;
|
||||
}
|
||||
|
||||
public CheckConstraint(String name, String constraint, String options) {
|
||||
this.name = name;
|
||||
this.constraint = constraint;
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
public CheckConstraint(String constraint) {
|
||||
this.constraint = constraint;
|
||||
}
|
||||
|
@ -54,12 +63,28 @@ public class CheckConstraint {
|
|||
this.constraint = constraint;
|
||||
}
|
||||
|
||||
public String getOptions() {
|
||||
return options;
|
||||
}
|
||||
|
||||
public void setOptions(String options) {
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #constraintString(Dialect)} instead.
|
||||
*/
|
||||
@Deprecated(since = "7.0")
|
||||
public String constraintString() {
|
||||
return name == null
|
||||
? " check (" + constraint + ")"
|
||||
: " constraint " + name + " check (" + constraint + ")";
|
||||
}
|
||||
|
||||
public String constraintString(Dialect dialect) {
|
||||
return dialect.getCheckConstraintString( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
if ( object instanceof CheckConstraint ) {
|
||||
|
|
|
@ -137,7 +137,7 @@ class ColumnDefinitions {
|
|||
long anonConstraints = checkConstraints.stream().filter(CheckConstraint::isAnonymous).count();
|
||||
if ( anonConstraints == 1 ) {
|
||||
for ( CheckConstraint constraint : checkConstraints ) {
|
||||
definition.append( constraint.constraintString() );
|
||||
definition.append( constraint.constraintString( dialect ) );
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -159,7 +159,7 @@ class ColumnDefinitions {
|
|||
}
|
||||
for ( CheckConstraint constraint : checkConstraints ) {
|
||||
if ( constraint.isNamed() ) {
|
||||
definition.append( constraint.constraintString() );
|
||||
definition.append( constraint.constraintString( dialect ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -173,7 +173,7 @@ public class StandardTableExporter implements Exporter<Table> {
|
|||
protected void applyTableCheck(Table table, StringBuilder buf) {
|
||||
if ( dialect.supportsTableCheck() ) {
|
||||
for ( CheckConstraint constraint : table.getChecks() ) {
|
||||
buf.append( "," ).append( constraint.constraintString() );
|
||||
buf.append( "," ).append( constraint.constraintString( dialect ) );
|
||||
}
|
||||
final AggregateSupport aggregateSupport = dialect.getAggregateSupport();
|
||||
if ( aggregateSupport != null && aggregateSupport.supportsComponentCheckConstraints() ) {
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
package org.hibernate.orm.test.schemaupdate.checkconstraint.column;
|
||||
|
||||
public interface Another {
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package org.hibernate.orm.test.schemaupdate.checkconstraint.column;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
@Entity(name = "AnotherTestEntity")
|
||||
@Table(name = "ANOTHER_TEST_ENTITY")
|
||||
public class AnotherTestEntity implements Another {
|
||||
@Id
|
||||
private Long id;
|
||||
|
||||
@Column(name = "FIRST_NAME")
|
||||
private String firstName;
|
||||
}
|
|
@ -0,0 +1,153 @@
|
|||
package org.hibernate.orm.test.schemaupdate.checkconstraint.column;
|
||||
|
||||
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.DialectFeatureChecks;
|
||||
import org.hibernate.testing.orm.junit.JiraKey;
|
||||
import org.hibernate.testing.orm.junit.RequiresDialectFeature;
|
||||
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.assertj.core.api.AssertionsForClassTypes.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
@BaseUnitTest
|
||||
@JiraKey("HHH-18054")
|
||||
@RequiresDialectFeature(feature = DialectFeatureChecks.SupportsColumnCheck.class)
|
||||
public class ColumnCheckConstraintTest {
|
||||
static final String COLUMN_CONSTRAINTS = "name_column <> null";
|
||||
|
||||
static final String ONE_TO_ONE_JOIN_COLUMN_CONSTRAINTS = "ID <> null";
|
||||
static final String ONE_TO_MANY_JOIN_COLUMN_CONSTRAINTS = "ID > 2";
|
||||
static final String MANY_TO_ONE_JOIN_COLUMN_CONSTRAINTS = "ID > 3 ";
|
||||
static final String MANY_TO_MANY_JOIN_COLUMN_CONSTRAINTS = "ID > 4";
|
||||
static final String MANY_TO_MANY_INVERSE_JOIN_COLUMN_CONSTRAINTS = "ID > 5";
|
||||
static final String ANY_JOIN_COLUMN_CONSTRAINTS = "ID > 5";
|
||||
|
||||
static final String ONE_TO_ONE_JOIN_COLUMN_NAME = "ONE_TO_ONE_JOIN_COLUMN_NAME";
|
||||
static final String ONE_TO_MANY_JOIN_COLUMN_NAME = "ONE_TO_MAIN_JOIN_COLUMN_NAME";
|
||||
static final String MANY_TO_ONE_JOIN_COLUMN_NAME = "MANY_TO_ONE_JOIN_COLUMN_NAME";
|
||||
static final String MANY_TO_MANY_JOIN_COLUMN_NAME = "MANY_TO_MANY_JOIN_COLUMN_NAME";
|
||||
static final String MANY_TO_MANY_INVERSE_JOIN_COLUMN_NAME = "MANY_TO_MANY_INVERSE_JOIN_COLUMN_NAME";
|
||||
|
||||
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 testColumnConstraintsAreApplied() throws Exception {
|
||||
createSchema( TestEntity.class, AnotherTestEntity.class );
|
||||
String fileContent = new String( Files.readAllBytes( output.toPath() ) ).toLowerCase()
|
||||
.replace( System.lineSeparator(), "" );
|
||||
assertThat( fileContent.toUpperCase( Locale.ROOT ) ).contains( COLUMN_CONSTRAINTS.toUpperCase( Locale.ROOT ) );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJoinColumConstraintsAreApplied() throws Exception {
|
||||
createSchema( TestEntity.class, AnotherTestEntity.class );
|
||||
String[] fileContent = new String( Files.readAllBytes( output.toPath() ) ).toLowerCase()
|
||||
.split( System.lineSeparator() );
|
||||
assertTrue( tableCreationStatementContainsConstraints(
|
||||
fileContent,
|
||||
"TEST_ENTITY",
|
||||
MANY_TO_ONE_JOIN_COLUMN_CONSTRAINTS
|
||||
), "Check Constraints on ManyToOne join table have not been created" );
|
||||
assertTrue( tableCreationStatementContainsConstraints(
|
||||
fileContent,
|
||||
"TEST_ENTITY",
|
||||
ONE_TO_ONE_JOIN_COLUMN_CONSTRAINTS
|
||||
), "Check Constraints on OneToOne join table have not been created" );
|
||||
assertTrue( tableCreationStatementContainsConstraints(
|
||||
fileContent,
|
||||
"ANOTHER_TEST_ENTITY",
|
||||
ONE_TO_MANY_JOIN_COLUMN_CONSTRAINTS
|
||||
), "Check Constraints on OneToOne join table have not been created" );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJoinColumOfJoinTableConstraintsAreApplied() throws Exception {
|
||||
createSchema( TestEntity.class, AnotherTestEntity.class );
|
||||
String[] fileContent = new String( Files.readAllBytes( output.toPath() ) ).toLowerCase()
|
||||
.split( System.lineSeparator() );
|
||||
assertTrue( tableCreationStatementContainsConstraints(
|
||||
fileContent,
|
||||
"MANY_T0_MANY_TABLE",
|
||||
MANY_TO_MANY_JOIN_COLUMN_CONSTRAINTS
|
||||
), "Join column Check Constraints on ManyToMany join table have not been created" );
|
||||
assertTrue( tableCreationStatementContainsConstraints(
|
||||
fileContent,
|
||||
"MANY_T0_MANY_TABLE",
|
||||
MANY_TO_MANY_INVERSE_JOIN_COLUMN_CONSTRAINTS
|
||||
), "Inverse join column Check Constraints on ManyToMany join table have not been created" );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAnyJoinTableConstraintsAreApplied() throws Exception {
|
||||
createSchema( TestEntity.class, AnotherTestEntity.class );
|
||||
String[] fileContent = new String( Files.readAllBytes( output.toPath() ) ).toLowerCase()
|
||||
.split( System.lineSeparator() );
|
||||
assertTrue( tableCreationStatementContainsConstraints(
|
||||
fileContent,
|
||||
"TEST_ENTITY",
|
||||
ANY_JOIN_COLUMN_CONSTRAINTS
|
||||
), "Check Constraints on Any join table have not been created" );
|
||||
}
|
||||
|
||||
private static boolean tableCreationStatementContainsConstraints(
|
||||
String[] fileContent,
|
||||
String tableName,
|
||||
String secondaryTableConstraints) {
|
||||
for ( int i = 0; i < fileContent.length; i++ ) {
|
||||
String statement = fileContent[i].toUpperCase( Locale.ROOT );
|
||||
if ( statement.contains( "CREATE TABLE " + tableName.toUpperCase( Locale.ROOT ) ) ) {
|
||||
if ( statement.contains( secondaryTableConstraints.toUpperCase( Locale.ROOT ) ) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
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 )
|
||||
.create( EnumSet.of( TargetType.SCRIPT ), metadata );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,120 @@
|
|||
package org.hibernate.orm.test.schemaupdate.checkconstraint.column;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.annotations.Any;
|
||||
import org.hibernate.annotations.AnyDiscriminator;
|
||||
import org.hibernate.annotations.AnyDiscriminatorValue;
|
||||
import org.hibernate.annotations.AnyDiscriminatorValues;
|
||||
import org.hibernate.annotations.AnyKeyJavaClass;
|
||||
|
||||
import jakarta.persistence.CheckConstraint;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.DiscriminatorType;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.JoinTable;
|
||||
import jakarta.persistence.ManyToMany;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.OneToMany;
|
||||
import jakarta.persistence.OneToOne;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
@Entity
|
||||
@Table(name = "TEST_ENTITY")
|
||||
public class TestEntity {
|
||||
@Id
|
||||
private Long id;
|
||||
|
||||
@Column(
|
||||
name = "name_column",
|
||||
check = {
|
||||
@CheckConstraint(
|
||||
name = "column_constraint",
|
||||
constraint = ColumnCheckConstraintTest.COLUMN_CONSTRAINTS,
|
||||
options = "enforced"
|
||||
)
|
||||
})
|
||||
private String name;
|
||||
|
||||
@OneToOne
|
||||
@JoinColumn(
|
||||
name = ColumnCheckConstraintTest.ONE_TO_ONE_JOIN_COLUMN_NAME,
|
||||
check = {
|
||||
@CheckConstraint(
|
||||
name = "ONE_TO_ONE_JOIN_COLUMN_CONSTRAINT",
|
||||
constraint = ColumnCheckConstraintTest.ONE_TO_ONE_JOIN_COLUMN_CONSTRAINTS
|
||||
)
|
||||
}
|
||||
)
|
||||
private AnotherTestEntity entity;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(
|
||||
name = ColumnCheckConstraintTest.MANY_TO_ONE_JOIN_COLUMN_NAME,
|
||||
check = {
|
||||
@CheckConstraint(
|
||||
name = "MANY_TO_ONE_JOIN_COLUMN_CONSTRAINT",
|
||||
constraint = ColumnCheckConstraintTest.MANY_TO_ONE_JOIN_COLUMN_CONSTRAINTS
|
||||
)
|
||||
}
|
||||
)
|
||||
private AnotherTestEntity testEntity;
|
||||
|
||||
@OneToMany
|
||||
@JoinColumn(
|
||||
name = ColumnCheckConstraintTest.ONE_TO_MANY_JOIN_COLUMN_NAME,
|
||||
check = {
|
||||
@CheckConstraint(
|
||||
name = "ONE_TO_MANY_JOIN_COLUMN_CONSTRAINT",
|
||||
constraint = ColumnCheckConstraintTest.ONE_TO_MANY_JOIN_COLUMN_CONSTRAINTS
|
||||
)
|
||||
}
|
||||
)
|
||||
private List<AnotherTestEntity> testEntities;
|
||||
|
||||
@ManyToMany
|
||||
@JoinTable(
|
||||
name = "MANY_T0_MANY_TABLE",
|
||||
inverseJoinColumns = {
|
||||
@JoinColumn(
|
||||
name = ColumnCheckConstraintTest.MANY_TO_MANY_INVERSE_JOIN_COLUMN_NAME,
|
||||
check = {
|
||||
@CheckConstraint(
|
||||
name = "MANY_TO_MANY_INVERSE_JOIN_COLUMN_CONSTRAINT",
|
||||
constraint = ColumnCheckConstraintTest.MANY_TO_MANY_INVERSE_JOIN_COLUMN_CONSTRAINTS
|
||||
)
|
||||
}
|
||||
),
|
||||
},
|
||||
joinColumns = {
|
||||
@JoinColumn(
|
||||
name = ColumnCheckConstraintTest.MANY_TO_MANY_JOIN_COLUMN_NAME,
|
||||
check = {
|
||||
@CheckConstraint(
|
||||
name = "MANY_TO_MANY_JOIN_COLUMN_CONSTRAINT",
|
||||
constraint = ColumnCheckConstraintTest.MANY_TO_MANY_JOIN_COLUMN_CONSTRAINTS
|
||||
)
|
||||
}
|
||||
),
|
||||
}
|
||||
)
|
||||
private List<AnotherTestEntity> testEntities2;
|
||||
|
||||
@Any
|
||||
@AnyDiscriminator(DiscriminatorType.STRING)
|
||||
@AnyDiscriminatorValues({
|
||||
@AnyDiscriminatorValue(discriminator = "S", entity = AnotherTestEntity.class),
|
||||
})
|
||||
@AnyKeyJavaClass(Long.class)
|
||||
@Column(name = "another_type")
|
||||
@JoinColumn(name = "another_id",
|
||||
check = {
|
||||
@CheckConstraint(
|
||||
name = "ANY_JOIN_COLUMN_CONSTRAINT",
|
||||
constraint = ColumnCheckConstraintTest.ANY_JOIN_COLUMN_CONSTRAINTS
|
||||
)
|
||||
})
|
||||
private Another another;
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
package org.hibernate.orm.test.schemaupdate.checkconstraint.table;
|
||||
|
||||
public interface Another {
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package org.hibernate.orm.test.schemaupdate.checkconstraint.table;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Id;
|
||||
|
||||
@Entity(name = "AnotherTestEntity")
|
||||
public class AnotherTestEntity implements Another {
|
||||
@Id
|
||||
private Long id;
|
||||
|
||||
@Column(name = "FIRST_NAME")
|
||||
private String firstName;
|
||||
}
|
|
@ -0,0 +1,111 @@
|
|||
package org.hibernate.orm.test.schemaupdate.checkconstraint.table;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.annotations.Any;
|
||||
import org.hibernate.annotations.AnyDiscriminator;
|
||||
import org.hibernate.annotations.AnyDiscriminatorValue;
|
||||
import org.hibernate.annotations.AnyDiscriminatorValues;
|
||||
import org.hibernate.annotations.AnyKeyJavaClass;
|
||||
|
||||
import jakarta.persistence.CheckConstraint;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.DiscriminatorType;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.JoinTable;
|
||||
import jakarta.persistence.ManyToMany;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.OneToMany;
|
||||
import jakarta.persistence.OneToOne;
|
||||
import jakarta.persistence.SecondaryTable;
|
||||
|
||||
@Entity(name = "TEST_ENTITY_2")
|
||||
@SecondaryTable(
|
||||
name = TableCheckConstraintTest.SECONDARY_TABLE_NAME,
|
||||
check = {
|
||||
@CheckConstraint(
|
||||
name = "TABLE_CONSTRAINT",
|
||||
constraint = TableCheckConstraintTest.SECONDARY_TABLE_CONSTRAINTS
|
||||
)
|
||||
}
|
||||
)
|
||||
public class EntityWithSecondaryTables {
|
||||
@Id
|
||||
private Long id;
|
||||
|
||||
@Column(name = "NAME_COLUMN")
|
||||
private String name;
|
||||
|
||||
@Column(name = "SECOND_NAME", table = TableCheckConstraintTest.SECONDARY_TABLE_NAME)
|
||||
private String secondName;
|
||||
|
||||
@OneToOne
|
||||
@JoinTable(
|
||||
name = TableCheckConstraintTest.ONE_TO_ONE_JOIN_TABLE_NAME,
|
||||
check = {
|
||||
@CheckConstraint(
|
||||
name = "ONE_TO_ONE_JOIN_TABLE_CONSTRAINT",
|
||||
constraint = TableCheckConstraintTest.ONE_TO_ONE_JOIN_TABLE_CONSTRAINTS
|
||||
)
|
||||
}
|
||||
)
|
||||
private AnotherTestEntity entity;
|
||||
|
||||
@ManyToOne
|
||||
@JoinTable(
|
||||
name = TableCheckConstraintTest.MANY_TO_ONE_JOIN_TABLE_NAME,
|
||||
check = {
|
||||
@CheckConstraint(
|
||||
name = "MANY_TO_ONE_JOIN_TABLE_CONSTRAINT",
|
||||
constraint = TableCheckConstraintTest.MANY_TO_ONE_JOIN_TABLE_CONSTRAINTS
|
||||
)
|
||||
}
|
||||
)
|
||||
private AnotherTestEntity testEntity;
|
||||
|
||||
@OneToMany
|
||||
@JoinTable(
|
||||
name = TableCheckConstraintTest.ONE_TO_MANY_JOIN_TABLE_NAME,
|
||||
check = {
|
||||
@CheckConstraint(
|
||||
name = "ONE_TO_MANY_JOIN_TABLE_CONSTRAINT",
|
||||
constraint = TableCheckConstraintTest.ONE_TO_MANY_JOIN_TABLE_CONSTRAINTS
|
||||
)
|
||||
}
|
||||
)
|
||||
private List<AnotherTestEntity> testEntities;
|
||||
|
||||
@ManyToMany
|
||||
@JoinTable(
|
||||
name = TableCheckConstraintTest.MANY_TO_MANY_JOIN_TABLE_NAME,
|
||||
check = {
|
||||
@CheckConstraint(
|
||||
name = "MANY_TO_MANY_JOIN_TABLE_CONSTRAINT",
|
||||
constraint = TableCheckConstraintTest.MANY_TO_MANY_JOIN_TABLE_CONSTRAINTS
|
||||
)
|
||||
}
|
||||
)
|
||||
private List<AnotherTestEntity> testEntities2;
|
||||
|
||||
@Any
|
||||
@AnyDiscriminator(DiscriminatorType.STRING)
|
||||
@AnyDiscriminatorValues({
|
||||
@AnyDiscriminatorValue(discriminator = "S", entity = AnotherTestEntity.class),
|
||||
})
|
||||
@AnyKeyJavaClass(Long.class)
|
||||
@Column(name = "another_type")
|
||||
@JoinColumn(name = "another_id")
|
||||
@JoinTable(
|
||||
name = TableCheckConstraintTest.ANY_JOIN_TABLE_NAME,
|
||||
check = {
|
||||
@CheckConstraint(
|
||||
name = "ANY_JOIN_TABLE_CONSTRAINT",
|
||||
constraint = TableCheckConstraintTest.ANY_JOIN_TABLE_CONSTRAINTS
|
||||
)
|
||||
}
|
||||
)
|
||||
private Another another;
|
||||
}
|
||||
|
|
@ -0,0 +1,153 @@
|
|||
package org.hibernate.orm.test.schemaupdate.checkconstraint.table;
|
||||
|
||||
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.DialectFeatureChecks;
|
||||
import org.hibernate.testing.orm.junit.JiraKey;
|
||||
import org.hibernate.testing.orm.junit.RequiresDialectFeature;
|
||||
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.assertj.core.api.AssertionsForClassTypes.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
@BaseUnitTest
|
||||
@JiraKey("HHH-18054")
|
||||
@RequiresDialectFeature(feature = DialectFeatureChecks.SupportsColumnCheck.class)
|
||||
public class TableCheckConstraintTest {
|
||||
static final String CONSTRAINTS = "NAME_COLUMN <> null";
|
||||
static final String SECONDARY_TABLE_CONSTRAINTS = "SECOND_NAME <> null";
|
||||
static final String ONE_TO_ONE_JOIN_TABLE_CONSTRAINTS = "ID <> null";
|
||||
static final String ONE_TO_MANY_JOIN_TABLE_CONSTRAINTS = "ID > 2";
|
||||
static final String MANY_TO_ONE_JOIN_TABLE_CONSTRAINTS = "ID > 3 ";
|
||||
static final String MANY_TO_MANY_JOIN_TABLE_CONSTRAINTS = "ID > 4";
|
||||
static final String ANY_JOIN_TABLE_CONSTRAINTS = "ID > 5";
|
||||
|
||||
static final String SECONDARY_TABLE_NAME = "SECOND_TABLE_NAME";
|
||||
static final String ONE_TO_ONE_JOIN_TABLE_NAME = "ONE_TO_ONE_JOIN_TABLE_NAME";
|
||||
static final String ONE_TO_MANY_JOIN_TABLE_NAME = "ONE_TO_MAIN_JOIN_TABLE_NAME";
|
||||
static final String MANY_TO_ONE_JOIN_TABLE_NAME = "MANY_TO_ONE_JOIN_TABLE_NAME";
|
||||
static final String MANY_TO_MANY_JOIN_TABLE_NAME = "MANY_TO_MANY_JOIN_TABLE_NAME";
|
||||
static final String ANY_JOIN_TABLE_NAME = "ANY_JOIN_TABLE_NAME";
|
||||
|
||||
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 testTableConstraintsAreApplied() throws Exception {
|
||||
createSchema( TestEntity.class );
|
||||
String fileContent = new String( Files.readAllBytes( output.toPath() ) ).toLowerCase()
|
||||
.replace( System.lineSeparator(), "" );
|
||||
assertThat( fileContent.toUpperCase( Locale.ROOT ) ).contains( CONSTRAINTS.toUpperCase( Locale.ROOT ) );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSecondaryTableConstraintsAreApplied() throws Exception {
|
||||
createSchema( EntityWithSecondaryTables.class, AnotherTestEntity.class );
|
||||
String[] fileContent = new String( Files.readAllBytes( output.toPath() ) ).toLowerCase()
|
||||
.split( System.lineSeparator() );
|
||||
assertTrue( tableCreationStatementContainsConstraints(
|
||||
fileContent,
|
||||
SECONDARY_TABLE_NAME,
|
||||
SECONDARY_TABLE_CONSTRAINTS
|
||||
), "Check Constraints on secondary table have not been created" );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJoinTableConstraintsAreApplied() throws Exception {
|
||||
createSchema( EntityWithSecondaryTables.class, AnotherTestEntity.class );
|
||||
String[] fileContent = new String( Files.readAllBytes( output.toPath() ) ).toLowerCase()
|
||||
.split( System.lineSeparator() );
|
||||
assertTrue( tableCreationStatementContainsConstraints(
|
||||
fileContent,
|
||||
MANY_TO_ONE_JOIN_TABLE_NAME,
|
||||
MANY_TO_ONE_JOIN_TABLE_CONSTRAINTS
|
||||
), "Check Constraints on ManyToOne join table have not been created" );
|
||||
assertTrue( tableCreationStatementContainsConstraints(
|
||||
fileContent,
|
||||
MANY_TO_MANY_JOIN_TABLE_NAME,
|
||||
MANY_TO_MANY_JOIN_TABLE_CONSTRAINTS
|
||||
), "Check Constraints on ManyToMany join table have not been created" );
|
||||
assertTrue( tableCreationStatementContainsConstraints(
|
||||
fileContent,
|
||||
ONE_TO_ONE_JOIN_TABLE_NAME,
|
||||
ONE_TO_ONE_JOIN_TABLE_CONSTRAINTS
|
||||
), "Check Constraints on OneToOne join table have not been created" );
|
||||
assertTrue( tableCreationStatementContainsConstraints(
|
||||
fileContent,
|
||||
ONE_TO_MANY_JOIN_TABLE_NAME,
|
||||
ONE_TO_MANY_JOIN_TABLE_CONSTRAINTS
|
||||
), "Check Constraints on OneToOne join table have not been created" );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAnyJoinTableConstraintsAreApplied() throws Exception {
|
||||
createSchema( EntityWithSecondaryTables.class, AnotherTestEntity.class );
|
||||
String[] fileContent = new String( Files.readAllBytes( output.toPath() ) ).toLowerCase()
|
||||
.split( System.lineSeparator() );
|
||||
assertTrue( tableCreationStatementContainsConstraints(
|
||||
fileContent,
|
||||
ANY_JOIN_TABLE_NAME,
|
||||
ANY_JOIN_TABLE_CONSTRAINTS
|
||||
), "Check Constraints on Any join table have not been created" );
|
||||
}
|
||||
|
||||
private static boolean tableCreationStatementContainsConstraints(
|
||||
String[] fileContent,
|
||||
String tableName,
|
||||
String secondaryTableConstraints) {
|
||||
for ( int i = 0; i < fileContent.length; i++ ) {
|
||||
String statement = fileContent[i].toUpperCase( Locale.ROOT );
|
||||
if ( statement.contains( "CREATE TABLE " + tableName.toUpperCase( Locale.ROOT ) ) ) {
|
||||
if ( statement.contains( secondaryTableConstraints.toUpperCase( Locale.ROOT ) ) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
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 )
|
||||
.create( EnumSet.of( TargetType.SCRIPT ), metadata );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package org.hibernate.orm.test.schemaupdate.checkconstraint.table;
|
||||
|
||||
import jakarta.persistence.CheckConstraint;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
@Entity(name = "TEST_ENTITY_1")
|
||||
@Table(
|
||||
name = "TEST_ENTITY_TABLE",
|
||||
check = {
|
||||
@CheckConstraint(
|
||||
name = "TABLE_CONSTRAINT",
|
||||
constraint = TableCheckConstraintTest.CONSTRAINTS
|
||||
)
|
||||
}
|
||||
)
|
||||
public class TestEntity {
|
||||
@Id
|
||||
private Long id;
|
||||
|
||||
@Column(name = "NAME_COLUMN")
|
||||
private String name;
|
||||
}
|
Loading…
Reference in New Issue