diff --git a/documentation/src/test/java/org/hibernate/userguide/schema/CheckTest.java b/documentation/src/test/java/org/hibernate/userguide/schema/CheckTest.java index ed05b46322..62a145a2c9 100644 --- a/documentation/src/test/java/org/hibernate/userguide/schema/CheckTest.java +++ b/documentation/src/test/java/org/hibernate/userguide/schema/CheckTest.java @@ -6,10 +6,12 @@ */ package org.hibernate.userguide.schema; +import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.Id; import jakarta.persistence.PersistenceException; +import jakarta.persistence.SecondaryTable; import org.hibernate.annotations.Check; import org.hibernate.annotations.NaturalId; import org.hibernate.dialect.H2Dialect; @@ -20,6 +22,8 @@ import org.hibernate.orm.test.jpa.BaseEntityManagerFunctionalTestCase; import org.hibernate.testing.RequiresDialect; import org.junit.Test; +import java.time.LocalDate; + import static org.hibernate.testing.transaction.TransactionUtil.doInJPA; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; @@ -120,7 +124,9 @@ public class CheckTest extends BaseEntityManagerFunctionalTestCase { //tag::schema-generation-database-checks-example[] @Entity(name = "Book") - @Check(constraints = "CASE WHEN isbn IS NOT NULL THEN LENGTH(isbn) = 13 ELSE true END") + @Check(name = "ValidIsbn", constraints = "CASE WHEN isbn IS NOT NULL THEN LENGTH(isbn) = 13 ELSE true END") + @SecondaryTable(name = "BookEdition") + @Check(name = "PositiveEdition", constraints = "edition > 0") public static class Book { @Id @@ -133,6 +139,12 @@ public class CheckTest extends BaseEntityManagerFunctionalTestCase { private Double price; + @Column(table = "BookEdition") + private int edition = 1; + + @Column(table = "BookEdition") + private LocalDate editionDate; + //Getters and setters omitted for brevity //end::schema-generation-database-checks-example[] diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/Check.java b/hibernate-core/src/main/java/org/hibernate/annotations/Check.java index 5b5d041b5c..d22c04b164 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/Check.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/Check.java @@ -6,6 +6,7 @@ */ package org.hibernate.annotations; +import java.lang.annotation.Repeatable; import java.lang.annotation.Retention; import java.lang.annotation.Target; @@ -17,8 +18,19 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * Specifies a {@code check} constraint to be included in the generated DDL. *
- * Useful for secondary tables, otherwise use {@link Check}. * - * @see Check + * @deprecated use {@link Check}. */ + @Deprecated(since = "6.2") String checkConstraint() default ""; /** @@ -61,6 +66,7 @@ public @interface Table { /** * Specifies a foreign key of a secondary table, which points back to the primary table. * + * @apiNote Only relevant to secondary tables * @deprecated use {@link jakarta.persistence.SecondaryTable#foreignKey()} */ @Deprecated(since = "6.0", forRemoval = true) @@ -74,9 +80,8 @@ public @interface Table { /** * If enabled, Hibernate will never insert or update the columns of the secondary table. - *
- * Only applies to secondary tables. * + * @apiNote Only relevant to secondary tables * @deprecated use {@link SecondaryRow#owned()} */ @Deprecated(since = "6.2") @@ -87,7 +92,7 @@ public @interface Table { * would not all be null, and will always use an outer join to read the columns. Thus, * by default, Hibernate avoids creating a row of null values. * - * @apiNote Only relevant for secondary tables + * @apiNote Only relevant to secondary tables * @deprecated use {@link SecondaryRow#optional()} */ @Deprecated(since = "6.2") @@ -95,9 +100,8 @@ public @interface Table { /** * Defines a custom SQL insert statement. - *
- * Only applies to secondary tables. * + * @apiNote Only relevant to secondary tables * @deprecated use {@link SQLInsert#table()} to specify the secondary table */ @Deprecated(since="6.2") @@ -105,9 +109,8 @@ public @interface Table { /** * Defines a custom SQL update statement. - *
- * Only applies to secondary tables. * + * @apiNote Only relevant to secondary tables * @deprecated use {@link SQLInsert#table()} to specify the secondary table */ @Deprecated(since="6.2") @@ -115,9 +118,8 @@ public @interface Table { /** * Defines a custom SQL delete statement. - *
- * Only applies to secondary tables.
*
+ * @apiNote Only relevant to secondary tables
* @deprecated use {@link SQLInsert#table()} to specify the secondary table
*/
@Deprecated(since="6.2")
diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/Tables.java b/hibernate-core/src/main/java/org/hibernate/annotations/Tables.java
index 40d0825ea5..e1379f6802 100644
--- a/hibernate-core/src/main/java/org/hibernate/annotations/Tables.java
+++ b/hibernate-core/src/main/java/org/hibernate/annotations/Tables.java
@@ -16,9 +16,12 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
* A grouping of {@link Table}s.
*
* @author Emmanuel Bernard
+ *
+ * @deprecated since {@link Table} is deprecated
*/
@Target(TYPE)
@Retention(RUNTIME)
+@Deprecated(since = "6.2", forRemoval = true)
public @interface Tables {
/**
* The table grouping.
diff --git a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/AnnotatedColumn.java b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/AnnotatedColumn.java
index eb36e3da6a..1405ab420c 100644
--- a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/AnnotatedColumn.java
+++ b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/AnnotatedColumn.java
@@ -27,6 +27,7 @@ import org.hibernate.boot.spi.PropertyData;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.mapping.AggregateColumn;
+import org.hibernate.mapping.CheckConstraint;
import org.hibernate.mapping.Column;
import org.hibernate.mapping.Component;
import org.hibernate.mapping.Formula;
@@ -83,6 +84,7 @@ public class AnnotatedColumn {
private String generatedAs;
// private String comment;
+ private String checkConstraintName;
private String checkConstraint;
private AnnotatedColumns parent;
@@ -124,10 +126,6 @@ public class AnnotatedColumn {
return isNotEmpty( formulaString );
}
- public String getFormulaString() {
- return formulaString;
- }
-
public String getExplicitTableName() {
return explicitTableName;
}
@@ -188,16 +186,13 @@ public class AnnotatedColumn {
return defaultValue;
}
- public String getCheckConstraint() {
- return checkConstraint;
- }
-
public void setDefaultValue(String defaultValue) {
this.defaultValue = defaultValue;
}
- public void setCheckConstraint(String checkConstraint) {
- this.checkConstraint = checkConstraint;
+ public void setCheckConstraint(String name, String constraint) {
+ this.checkConstraintName = name;
+ this.checkConstraint = constraint;
}
// public String getComment() {
@@ -240,8 +235,8 @@ public class AnnotatedColumn {
if ( defaultValue != null ) {
mappingColumn.setDefaultValue( defaultValue );
}
- if ( checkConstraint !=null ) {
- mappingColumn.setCheckConstraint( checkConstraint );
+ if ( checkConstraint != null ) {
+ mappingColumn.setCheck( new CheckConstraint( checkConstraintName, checkConstraint ) );
}
// if ( isNotEmpty( comment ) ) {
// mappingColumn.setComment( comment );
@@ -280,7 +275,9 @@ public class AnnotatedColumn {
mappingColumn.setNullable( nullable );
mappingColumn.setSqlType( sqlType );
mappingColumn.setUnique( unique );
- mappingColumn.setCheckConstraint( checkConstraint );
+ if ( checkConstraint != null ) {
+ mappingColumn.setCheck( new CheckConstraint( checkConstraintName, checkConstraint ) );
+ }
mappingColumn.setDefaultValue( defaultValue );
if ( writeExpression != null ) {
@@ -817,7 +814,7 @@ public class AnnotatedColumn {
throw new AnnotationException("'@Check' may only be applied to single-column mappings but '"
+ property.getName() + "' maps to " + length + " columns (use a table-level '@Check')" );
}
- setCheckConstraint( check.constraints() );
+ setCheckConstraint( check.name().isEmpty() ? null : check.name(), check.constraints() );
}
}
else {
diff --git a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/ClassPropertyHolder.java b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/ClassPropertyHolder.java
index 3396418b1b..e9652c1a1a 100644
--- a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/ClassPropertyHolder.java
+++ b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/ClassPropertyHolder.java
@@ -226,7 +226,7 @@ public class ClassPropertyHolder extends AbstractPropertyHolder {
return join;
}
- private void addPropertyToPersistentClass(Property prop, XClass declaringClass) {
+ private void addPropertyToPersistentClass(Property property, XClass declaringClass) {
if ( declaringClass != null ) {
final InheritanceState inheritanceState = inheritanceStatePerClass.get( declaringClass );
if ( inheritanceState == null ) {
@@ -235,15 +235,15 @@ public class ClassPropertyHolder extends AbstractPropertyHolder {
);
}
if ( inheritanceState.isEmbeddableSuperclass() ) {
- persistentClass.addMappedSuperclassProperty( prop );
- addPropertyToMappedSuperclass( prop, declaringClass );
+ persistentClass.addMappedSuperclassProperty( property );
+ addPropertyToMappedSuperclass( property, declaringClass );
}
else {
- persistentClass.addProperty( prop );
+ persistentClass.addProperty( property );
}
}
else {
- persistentClass.addProperty( prop );
+ persistentClass.addProperty( property );
}
}
@@ -359,7 +359,7 @@ public class ClassPropertyHolder extends AbstractPropertyHolder {
}
}
- private void addPropertyToJoin(Property prop, XClass declaringClass, Join join) {
+ private void addPropertyToJoin(Property property, XClass declaringClass, Join join) {
if ( declaringClass != null ) {
final InheritanceState inheritanceState = inheritanceStatePerClass.get( declaringClass );
if ( inheritanceState == null ) {
@@ -368,15 +368,15 @@ public class ClassPropertyHolder extends AbstractPropertyHolder {
);
}
if ( inheritanceState.isEmbeddableSuperclass() ) {
- join.addMappedsuperclassProperty(prop);
- addPropertyToMappedSuperclass( prop, declaringClass );
+ join.addMappedsuperclassProperty( property );
+ addPropertyToMappedSuperclass( property, declaringClass );
}
else {
- join.addProperty( prop );
+ join.addProperty( property );
}
}
else {
- join.addProperty( prop );
+ join.addProperty( property );
}
}
diff --git a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/CollectionBinder.java b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/CollectionBinder.java
index 4ab3abbcc0..b14d7727c5 100644
--- a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/CollectionBinder.java
+++ b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/CollectionBinder.java
@@ -23,6 +23,7 @@ import org.hibernate.annotations.Bag;
import org.hibernate.annotations.BatchSize;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.Cascade;
+import org.hibernate.annotations.Check;
import org.hibernate.annotations.CollectionId;
import org.hibernate.annotations.CollectionIdJavaType;
import org.hibernate.annotations.CollectionIdJdbcType;
@@ -84,6 +85,7 @@ import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.mapping.Any;
import org.hibernate.mapping.Backref;
+import org.hibernate.mapping.CheckConstraint;
import org.hibernate.mapping.Collection;
import org.hibernate.mapping.Column;
import org.hibernate.mapping.Component;
@@ -1616,7 +1618,7 @@ public abstract class CollectionBinder {
foreignJoinColumns.getBuildingContext(),
inheritanceStatePerClass
) );
- foreignJoinColumns.setJoins( joins);
+ foreignJoinColumns.setJoins( joins );
collection.setCollectionTable( foreignJoinColumns.getTable() );
if ( LOG.isDebugEnabled() ) {
LOG.debugf( "Mapping collection: %s -> %s", collection.getRole(), collection.getCollectionTable().getName() );
@@ -1626,7 +1628,7 @@ public abstract class CollectionBinder {
handleWhere( false );
final PersistentClass targetEntity = persistentClasses.get( getElementType().getName() );
- bindCollectionSecondPass( targetEntity, foreignJoinColumns, onDeleteAction);
+ bindCollectionSecondPass( targetEntity, foreignJoinColumns );
if ( !collection.isInverse() && !collection.getKey().isNullable() ) {
createOneToManyBackref( oneToMany );
@@ -2056,84 +2058,35 @@ public abstract class CollectionBinder {
logManyToManySecondPass( oneToMany, isCollectionOfEntities, isManyToAny );
//check for user error
- detectManyToManyProblems(
- elementType,
- property,
- propertyHolder,
- isCollectionOfEntities,
- isManyToAny
- );
+ detectManyToManyProblems( elementType, isCollectionOfEntities, isManyToAny );
- if (isUnownedCollection()) {
- handleUnownedManyToMany(
- collection,
- joinColumns,
- elementType,
- targetEntity,
- isCollectionOfEntities
- );
+ if ( isUnownedCollection() ) {
+ handleUnownedManyToMany( elementType, targetEntity, isCollectionOfEntities );
}
else {
- handleOwnedManyToMany(
- collection,
- joinColumns,
- tableBinder,
- property,
- buildingContext,
- targetEntity,
- isCollectionOfEntities
- );
+ handleOwnedManyToMany( targetEntity, isCollectionOfEntities );
}
bindFilters( isCollectionOfEntities );
handleWhere( isCollectionOfEntities );
- bindCollectionSecondPass( targetEntity, joinColumns, onDeleteAction);
+ bindCollectionSecondPass( targetEntity, joinColumns );
if ( isCollectionOfEntities ) {
- final ManyToOne element = handleCollectionOfEntities(
- collection,
- elementType,
- notFoundAction,
- property,
- buildingContext,
- targetEntity,
- hqlOrderBy
- );
+ final ManyToOne element = handleCollectionOfEntities( elementType, targetEntity, hqlOrderBy );
bindManyToManyInverseForeignKey( targetEntity, inverseJoinColumns, element, oneToMany );
}
else if ( isManyToAny ) {
- handleManyToAny(
- collection,
- inverseJoinColumns,
- onDeleteAction,
- property,
- buildingContext
- );
+ handleManyToAny();
}
else {
- handleElementCollection(
- collection,
- elementColumns,
- isEmbedded,
- elementType,
- property,
- propertyHolder,
- hqlOrderBy
- );
+ handleElementCollection( elementType, hqlOrderBy );
}
checkFilterConditions( collection );
}
- private void handleElementCollection(
- Collection collection,
- AnnotatedColumns elementColumns,
- boolean isEmbedded,
- XClass elementType,
- XProperty property,
- PropertyHolder parentPropertyHolder,
- String hqlOrderBy) {
- // 'parentPropertyHolder' is the PropertyHolder for the owner of the collection
+ private void handleElementCollection(XClass elementType, String hqlOrderBy) {
+ // 'propertyHolder' is the PropertyHolder for the owner of the collection
// 'holder' is the CollectionPropertyHolder.
// 'property' is the collection XProperty
@@ -2141,7 +2094,7 @@ public abstract class CollectionBinder {
final AnnotatedClassType classType = annotatedElementType( isEmbedded, property, elementType );
final boolean primitive = classType == NONE;
if ( !primitive ) {
- parentPropertyHolder.startingProperty( property );
+ propertyHolder.startingProperty( property );
}
final CollectionPropertyHolder holder = buildPropertyHolder(
@@ -2149,7 +2102,7 @@ public abstract class CollectionBinder {
collection.getRole(),
elementClass,
property,
- parentPropertyHolder,
+ propertyHolder,
buildingContext
);
holder.prepare( property );
@@ -2157,18 +2110,15 @@ public abstract class CollectionBinder {
final Class extends CompositeUserType>> compositeUserType =
resolveCompositeUserType( property, elementClass, buildingContext );
if ( classType == EMBEDDABLE || compositeUserType != null ) {
- handleCompositeCollectionElement( collection, property, hqlOrderBy, elementClass, holder, compositeUserType );
+ handleCompositeCollectionElement( hqlOrderBy, elementClass, holder, compositeUserType );
}
else {
- handleCollectionElement( collection, elementColumns, elementType, property, hqlOrderBy, elementClass, holder );
+ handleCollectionElement( elementType, hqlOrderBy, elementClass, holder );
}
}
private void handleCollectionElement(
- Collection collection,
- AnnotatedColumns elementColumns,
XClass elementType,
- XProperty property,
String hqlOrderBy,
XClass elementClass,
CollectionPropertyHolder holder) {
@@ -2187,20 +2137,18 @@ public abstract class CollectionBinder {
property,
elementClass,
collection.getOwnerEntityName(),
- holder.resolveElementAttributeConverterDescriptor(property, elementClass)
+ holder.resolveElementAttributeConverterDescriptor( property, elementClass )
);
elementBinder.setPersistentClassName( propertyHolder.getEntityName() );
elementBinder.setAccessType( accessType );
collection.setElement( elementBinder.make() );
- final String orderBy = adjustUserSuppliedValueCollectionOrderingFragment(hqlOrderBy);
+ final String orderBy = adjustUserSuppliedValueCollectionOrderingFragment( hqlOrderBy );
if ( orderBy != null ) {
collection.setOrderBy( orderBy );
}
}
private void handleCompositeCollectionElement(
- Collection collection,
- XProperty property,
String hqlOrderBy,
XClass elementClass,
CollectionPropertyHolder holder,
@@ -2256,7 +2204,7 @@ public abstract class CollectionBinder {
}
}
- AnnotatedClassType annotatedElementType(
+ private AnnotatedClassType annotatedElementType(
boolean isEmbedded,
XProperty property,
XClass elementType) {
@@ -2301,14 +2249,7 @@ public abstract class CollectionBinder {
return elementColumns;
}
- private ManyToOne handleCollectionOfEntities(
- Collection collection,
- XClass elementType,
- NotFoundAction notFoundAction,
- XProperty property,
- MetadataBuildingContext buildingContext,
- PersistentClass collectionEntity,
- String hqlOrderBy) {
+ private ManyToOne handleCollectionOfEntities(XClass elementType, PersistentClass collectionEntity, String hqlOrderBy) {
final ManyToOne element = new ManyToOne( buildingContext, collection.getCollectionTable() );
collection.setElement( element );
element.setReferencedEntityName( elementType.getName() );
@@ -2339,8 +2280,9 @@ public abstract class CollectionBinder {
foreignKeyDefinition = joinColumnAnn.foreignKey().foreignKeyDefinition();
}
}
- if ( joinTableAnn.inverseForeignKey().value() == NO_CONSTRAINT
- || joinTableAnn.inverseForeignKey().value() == PROVIDER_DEFAULT
+ final ConstraintMode constraintMode = joinTableAnn.inverseForeignKey().value();
+ if ( constraintMode == NO_CONSTRAINT
+ || constraintMode == PROVIDER_DEFAULT
&& buildingContext.getBuildingOptions().isNoConstraintByDefault() ) {
element.disableForeignKey();
}
@@ -2353,12 +2295,7 @@ public abstract class CollectionBinder {
return element;
}
- private void handleManyToAny(
- Collection collection,
- AnnotatedJoinColumns inverseJoinColumns,
- OnDeleteAction onDeleteAction,
- XProperty property,
- MetadataBuildingContext buildingContext) {
+ private void handleManyToAny() {
//@ManyToAny
//Make sure that collTyp is never used during the @ManyToAny branch: it will be set to void.class
final PropertyData inferredData = new PropertyInferredData(
@@ -2414,25 +2351,20 @@ public abstract class CollectionBinder {
}
private void handleOwnedManyToMany(
- Collection collection,
- AnnotatedJoinColumns joinColumns,
- TableBinder associationTableBinder,
- XProperty property,
- MetadataBuildingContext context,
PersistentClass collectionEntity,
boolean isCollectionOfEntities) {
//TODO: only for implicit columns?
//FIXME NamingStrategy
- final InFlightMetadataCollector collector = context.getMetadataCollector();
+ final InFlightMetadataCollector collector = buildingContext.getMetadataCollector();
final PersistentClass owner = collection.getOwner();
joinColumns.setMappedBy(
owner.getEntityName(),
collector.getLogicalTableName( owner.getTable() ),
collector.getFromMappedBy( owner.getEntityName(), joinColumns.getPropertyName() )
);
- if ( isEmpty( associationTableBinder.getName() ) ) {
+ if ( isEmpty( tableBinder.getName() ) ) {
//default value
- associationTableBinder.setDefaultName(
+ tableBinder.setDefaultName(
owner.getClassName(),
owner.getEntityName(),
owner.getJpaEntityName(),
@@ -2444,15 +2376,26 @@ public abstract class CollectionBinder {
joinColumns.getPropertyName()
);
}
- associationTableBinder.setJPA2ElementCollection(
- !isCollectionOfEntities && property.isAnnotationPresent(ElementCollection.class)
+ tableBinder.setJPA2ElementCollection(
+ !isCollectionOfEntities && property.isAnnotationPresent( ElementCollection.class )
);
- collection.setCollectionTable( associationTableBinder.bind() );
+ Table collectionTable = tableBinder.bind();
+ collection.setCollectionTable( collectionTable );
+ handleCheck( collectionTable );
+ }
+
+ private void handleCheck(Table collectionTable) {
+ final Check check = getOverridableAnnotation( property, Check.class, buildingContext );
+ if ( check != null ) {
+ final String name = check.name();
+ final String constraint = check.constraints();
+ collectionTable.addCheck( name.isEmpty()
+ ? new CheckConstraint( constraint )
+ : new CheckConstraint( name, constraint ) );
+ }
}
private void handleUnownedManyToMany(
- Collection collection,
- AnnotatedJoinColumns joinColumns,
XClass elementType,
PersistentClass collectionEntity,
boolean isCollectionOfEntities) {
@@ -2468,7 +2411,7 @@ public abstract class CollectionBinder {
try {
otherSideProperty = collectionEntity.getRecursiveProperty( mappedBy );
}
- catch (MappingException e) {
+ catch ( MappingException e ) {
throw new AnnotationException( "Association '" + safeCollectionRole() +
"is 'mappedBy' a property named '" + mappedBy
+ "' which does not exist in the target entity '" + elementType.getName() + "'" );
@@ -2484,8 +2427,6 @@ public abstract class CollectionBinder {
private void detectManyToManyProblems(
XClass elementType,
- XProperty property,
- PropertyHolder parentPropertyHolder,
boolean isCollectionOfEntities,
boolean isManyToAny) {
@@ -2495,13 +2436,13 @@ public abstract class CollectionBinder {
+ "' targets the type '" + elementType.getName() + "' which is not an '@Entity' type" );
}
else if (isManyToAny) {
- if ( parentPropertyHolder.getJoinTable( property ) == null ) {
+ if ( propertyHolder.getJoinTable( property ) == null ) {
throw new AnnotationException( "Association '" + safeCollectionRole()
+ "' is a '@ManyToAny' and must specify a '@JoinTable'" );
}
}
else {
- final JoinTable joinTableAnn = parentPropertyHolder.getJoinTable( property );
+ final JoinTable joinTableAnn = propertyHolder.getJoinTable( property );
if ( joinTableAnn != null && joinTableAnn.inverseJoinColumns().length > 0 ) {
throw new AnnotationException( "Association '" + safeCollectionRole()
+ " has a '@JoinTable' with 'inverseJoinColumns' and targets the type '"
@@ -2576,10 +2517,7 @@ public abstract class CollectionBinder {
}
}
- private void bindCollectionSecondPass(
- PersistentClass targetEntity,
- AnnotatedJoinColumns joinColumns,
- OnDeleteAction onDeleteAction) {
+ private void bindCollectionSecondPass(PersistentClass targetEntity, AnnotatedJoinColumns joinColumns) {
if ( !isUnownedCollection() ) {
createSyntheticPropertyReference(
@@ -2710,8 +2648,8 @@ public abstract class CollectionBinder {
this.foreignJoinColumns = annotatedJoinColumns;
}
- public void setExplicitAssociationTable(boolean explicitAssocTable) {
- this.isExplicitAssociationTable = explicitAssocTable;
+ public void setExplicitAssociationTable(boolean isExplicitAssociationTable) {
+ this.isExplicitAssociationTable = isExplicitAssociationTable;
}
public void setElementColumns(AnnotatedColumns elementColumns) {
diff --git a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/EntityBinder.java b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/EntityBinder.java
index 19e1ee6fa2..7e86f72139 100644
--- a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/EntityBinder.java
+++ b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/EntityBinder.java
@@ -45,6 +45,7 @@ import org.hibernate.annotations.BatchSize;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.annotations.Check;
+import org.hibernate.annotations.Checks;
import org.hibernate.annotations.DiscriminatorFormula;
import org.hibernate.annotations.DiscriminatorOptions;
import org.hibernate.annotations.DynamicInsert;
@@ -52,6 +53,7 @@ import org.hibernate.annotations.DynamicUpdate;
import org.hibernate.annotations.Filter;
import org.hibernate.annotations.Filters;
import org.hibernate.annotations.ForeignKey;
+import org.hibernate.annotations.ForeignKey;
import org.hibernate.annotations.Immutable;
import org.hibernate.annotations.Loader;
import org.hibernate.annotations.NaturalIdCache;
@@ -101,6 +103,7 @@ import org.hibernate.engine.spi.FilterDefinition;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.jpa.event.spi.CallbackType;
import org.hibernate.mapping.BasicValue;
+import org.hibernate.mapping.CheckConstraint;
import org.hibernate.mapping.Component;
import org.hibernate.mapping.DependantValue;
import org.hibernate.mapping.Join;
@@ -210,6 +213,7 @@ public class EntityBinder {
entityBinder.bindEntity();
entityBinder.handleClassTable( inheritanceState, superEntity );
entityBinder.handleSecondaryTables();
+ entityBinder.handleCheck();
final PropertyHolder holder = buildPropertyHolder(
clazzToProcess,
persistentClass,
@@ -238,6 +242,33 @@ public class EntityBinder {
entityBinder.callTypeBinders( persistentClass );
}
+ private void handleCheck() {
+ if ( annotatedClass.isAnnotationPresent( Checks.class ) ) {
+ // if we have more than one of them they are not overrideable :-/
+ for ( Check check : annotatedClass.getAnnotation( Checks.class ).value() ) {
+ addCheckToEntity( check );
+ }
+ }
+ else {
+ final Check check = getOverridableAnnotation( annotatedClass, Check.class, context );
+ if ( check != null ) {
+ addCheckToEntity( check );
+ }
+ }
+ }
+
+ /**
+ * For now, we store it on the entity.
+ * Later we will come back and figure out which table it belongs to.
+ */
+ private void addCheckToEntity(Check check) {
+ final String name = check.name();
+ final String constraint = check.constraints();
+ persistentClass.addCheckConstraint( name.isEmpty()
+ ? new CheckConstraint( constraint )
+ : new CheckConstraint( name, constraint ) );
+ }
+
private void callTypeBinders(PersistentClass persistentClass) {
for ( Annotation containingAnnotation : findContainingAnnotations( annotatedClass, TypeBinderType.class ) ) {
final TypeBinderType binderType = containingAnnotation.annotationType().getAnnotation( TypeBinderType.class );
@@ -643,14 +674,12 @@ public class EntityBinder {
String catalog,
List {
protected void applyTableCheck(Table table, StringBuilder buf) {
if ( dialect.supportsTableCheck() ) {
- for ( String constraint : table.getCheckConstraints() ) {
- buf.append( ", check (" ).append( constraint ).append( ')' );
+ for ( CheckConstraint constraint : table.getChecks() ) {
+ buf.append( "," ).append( constraint.constraintString() );
}
final AggregateSupport aggregateSupport = dialect.getAggregateSupport();
if ( aggregateSupport != null && aggregateSupport.supportsComponentCheckConstraints() ) {
@@ -231,7 +232,8 @@ public class StandardTableExporter implements Exporter
{
}
else {
for ( Column subColumn : value.getColumns() ) {
- final String checkConstraint = subColumn.getCheckConstraint();
+ final CheckConstraint check = subColumn.getCheck();
+ final String checkConstraint = check == null ? null : check.getConstraint();
if ( !subColumn.isNullable() || checkConstraint != null ) {
final String subColumnName = subColumn.getQuotedName( dialect );
final String columnExpression = aggregateSupport.aggregateComponentCustomReadExpression(