Skip to content

HHH-19394 disable transient reference checking for read-only entities #10096

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@
*/
package org.hibernate.boot.model.internal;

import java.util.EnumSet;
import java.util.Locale;

import org.hibernate.AnnotationException;
import org.hibernate.AssertionFailure;
import org.hibernate.annotations.AnyDiscriminator;
import org.hibernate.annotations.AnyDiscriminatorImplicitValues;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;
import org.hibernate.annotations.Columns;
import org.hibernate.annotations.Formula;
import org.hibernate.annotations.OnDelete;
Expand All @@ -29,7 +31,7 @@
import jakarta.persistence.FetchType;
import jakarta.persistence.JoinTable;

import static org.hibernate.boot.model.internal.BinderHelper.getCascadeStrategy;
import static org.hibernate.boot.model.internal.BinderHelper.aggregateCascadeTypes;
import static org.hibernate.boot.model.internal.DialectOverridesAnnotationHelper.getOverridableAnnotation;
import static org.hibernate.boot.model.internal.BinderHelper.getPath;

Expand Down Expand Up @@ -67,7 +69,7 @@ static void bindAny(
}
}
bindAny(
getCascadeStrategy( null, hibernateCascade, false, context ),
aggregateCascadeTypes( null, hibernateCascade, false, context ),
//@Any has no cascade attribute
joinColumns,
onDeleteAnn == null ? null : onDeleteAnn.action(),
Expand All @@ -81,7 +83,7 @@ static void bindAny(
}

private static void bindAny(
String cascadeStrategy,
EnumSet<CascadeType> cascadeStrategy,
AnnotatedJoinColumns columns,
OnDeleteAction onDeleteAction,
Nullability nullability,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -908,26 +908,29 @@ public static FetchMode getFetchMode(FetchType fetch) {
};
}

public static String getCascadeStrategy(
jakarta.persistence.CascadeType[] ejbCascades,
Cascade hibernateCascadeAnnotation,
public static EnumSet<CascadeType> aggregateCascadeTypes(
jakarta.persistence.CascadeType[] cascadeTypes,
Cascade cascadeAnnotation,
boolean orphanRemoval,
MetadataBuildingContext context) {
final EnumSet<CascadeType> cascadeTypes = convertToHibernateCascadeType( ejbCascades );
final EnumSet<CascadeType> cascades =
convertToHibernateCascadeType( cascadeTypes );
final CascadeType[] hibernateCascades =
hibernateCascadeAnnotation == null ? null : hibernateCascadeAnnotation.value();
cascadeAnnotation == null
? null
: cascadeAnnotation.value();
if ( !isEmpty( hibernateCascades ) ) {
addAll( cascadeTypes, hibernateCascades );
addAll( cascades, hibernateCascades );
}
if ( orphanRemoval ) {
cascadeTypes.add( CascadeType.DELETE_ORPHAN );
cascadeTypes.add( CascadeType.REMOVE );
cascades.add( CascadeType.DELETE_ORPHAN );
cascades.add( CascadeType.REMOVE );
}
if ( cascadeTypes.contains( CascadeType.REPLICATE ) ) {
if ( cascades.contains( CascadeType.REPLICATE ) ) {
warnAboutDeprecatedCascadeType( CascadeType.REPLICATE );
}
cascadeTypes.addAll( context.getEffectiveDefaults().getDefaultCascadeTypes() );
return renderCascadeTypeList( cascadeTypes );
cascades.addAll( context.getEffectiveDefaults().getDefaultCascadeTypes() );
return cascades;
}

private static EnumSet<CascadeType> convertToHibernateCascadeType(jakarta.persistence.CascadeType[] cascades) {
Expand All @@ -951,7 +954,7 @@ private static CascadeType convertCascadeType(jakarta.persistence.CascadeType ca
};
}

private static String renderCascadeTypeList(EnumSet<CascadeType> cascadeTypes) {
public static String renderCascadeTypeList(EnumSet<CascadeType> cascadeTypes) {
final StringBuilder cascade = new StringBuilder();
for ( CascadeType cascadeType : cascadeTypes ) {
cascade.append( "," );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import java.lang.annotation.Annotation;
import java.util.Comparator;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
Expand All @@ -17,57 +18,7 @@
import org.hibernate.AssertionFailure;
import org.hibernate.FetchMode;
import org.hibernate.MappingException;
import org.hibernate.annotations.Bag;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheLayout;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.Check;
import org.hibernate.annotations.Checks;
import org.hibernate.annotations.CollectionId;
import org.hibernate.annotations.CollectionIdJavaType;
import org.hibernate.annotations.CollectionIdJdbcType;
import org.hibernate.annotations.CollectionIdJdbcTypeCode;
import org.hibernate.annotations.CollectionType;
import org.hibernate.annotations.Columns;
import org.hibernate.annotations.CompositeType;
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchProfileOverride;
import org.hibernate.annotations.Filter;
import org.hibernate.annotations.FilterJoinTable;
import org.hibernate.annotations.Formula;
import org.hibernate.annotations.HQLSelect;
import org.hibernate.annotations.Immutable;
import org.hibernate.annotations.LazyGroup;
import org.hibernate.annotations.ListIndexBase;
import org.hibernate.annotations.ListIndexJavaType;
import org.hibernate.annotations.ListIndexJdbcType;
import org.hibernate.annotations.ListIndexJdbcTypeCode;
import org.hibernate.annotations.ManyToAny;
import org.hibernate.annotations.MapKeyJavaType;
import org.hibernate.annotations.MapKeyJdbcType;
import org.hibernate.annotations.MapKeyJdbcTypeCode;
import org.hibernate.annotations.MapKeyMutability;
import org.hibernate.annotations.MapKeyType;
import org.hibernate.annotations.NotFound;
import org.hibernate.annotations.NotFoundAction;
import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;
import org.hibernate.annotations.OptimisticLock;
import org.hibernate.annotations.Parameter;
import org.hibernate.annotations.QueryCacheLayout;
import org.hibernate.annotations.SQLDelete;
import org.hibernate.annotations.SQLDeleteAll;
import org.hibernate.annotations.SQLInsert;
import org.hibernate.annotations.SQLJoinTableRestriction;
import org.hibernate.annotations.SQLOrder;
import org.hibernate.annotations.SQLRestriction;
import org.hibernate.annotations.SQLSelect;
import org.hibernate.annotations.SQLUpdate;
import org.hibernate.annotations.SoftDelete;
import org.hibernate.annotations.SortComparator;
import org.hibernate.annotations.SortNatural;
import org.hibernate.annotations.SqlFragmentAlias;
import org.hibernate.annotations.Synchronize;
import org.hibernate.annotations.*;
import org.hibernate.boot.model.IdentifierGeneratorDefinition;
import org.hibernate.boot.models.JpaAnnotations;
import org.hibernate.boot.models.annotations.internal.JoinColumnJpaAnnotation;
Expand Down Expand Up @@ -139,6 +90,7 @@
import static jakarta.persistence.ConstraintMode.NO_CONSTRAINT;
import static jakarta.persistence.ConstraintMode.PROVIDER_DEFAULT;
import static jakarta.persistence.FetchType.LAZY;
import static org.hibernate.annotations.CascadeType.DELETE_ORPHAN;
import static org.hibernate.boot.model.internal.AnnotatedClassType.EMBEDDABLE;
import static org.hibernate.boot.model.internal.AnnotatedClassType.NONE;
import static org.hibernate.boot.model.internal.AnnotatedColumn.buildColumnFromAnnotation;
Expand All @@ -147,11 +99,11 @@
import static org.hibernate.boot.model.internal.AnnotatedColumn.buildFormulaFromAnnotation;
import static org.hibernate.boot.model.internal.AnnotatedJoinColumns.buildJoinColumnsWithDefaultColumnSuffix;
import static org.hibernate.boot.model.internal.AnnotatedJoinColumns.buildJoinTableJoinColumns;
import static org.hibernate.boot.model.internal.BinderHelper.aggregateCascadeTypes;
import static org.hibernate.boot.model.internal.BinderHelper.buildAnyValue;
import static org.hibernate.boot.model.internal.BinderHelper.checkMappedByType;
import static org.hibernate.boot.model.internal.BinderHelper.createSyntheticPropertyReference;
import static org.hibernate.boot.model.internal.BinderHelper.extractFromPackage;
import static org.hibernate.boot.model.internal.BinderHelper.getCascadeStrategy;
import static org.hibernate.boot.model.internal.BinderHelper.getFetchMode;
import static org.hibernate.boot.model.internal.BinderHelper.getPath;
import static org.hibernate.boot.model.internal.BinderHelper.isDefault;
Expand Down Expand Up @@ -202,7 +154,7 @@ public abstract class CollectionBinder {
protected MemberDetails property;
private TypeDetails collectionElementType;
private TypeDetails targetEntity;
private String cascadeStrategy;
private EnumSet<CascadeType> cascadeTypes;
private String cacheConcurrencyStrategy;
private String cacheRegionName;
private CacheLayout queryCacheLayout;
Expand Down Expand Up @@ -514,12 +466,9 @@ private static String handleTargetEntity(
collectionBinder.setFkJoinColumns( joinColumns );
mappedBy = nullIfEmpty( oneToManyAnn.mappedBy() );
collectionBinder.setTargetEntity( oneToManyAnn.targetEntity() );
collectionBinder.setCascadeStrategy( getCascadeStrategy(
oneToManyAnn.cascade(),
hibernateCascade,
oneToManyAnn.orphanRemoval(),
context
) );
collectionBinder.setCascadeStrategy(
aggregateCascadeTypes( oneToManyAnn.cascade(), hibernateCascade,
oneToManyAnn.orphanRemoval(), context ) );
collectionBinder.setOneToMany( true );
}
else if ( elementCollectionAnn != null ) {
Expand All @@ -535,23 +484,15 @@ else if ( elementCollectionAnn != null ) {
else if ( manyToManyAnn != null ) {
mappedBy = nullIfEmpty( manyToManyAnn.mappedBy() );
collectionBinder.setTargetEntity( manyToManyAnn.targetEntity() );
collectionBinder.setCascadeStrategy( getCascadeStrategy(
manyToManyAnn.cascade(),
hibernateCascade,
false,
context
) );
collectionBinder.setCascadeStrategy(
aggregateCascadeTypes( manyToManyAnn.cascade(), hibernateCascade, false, context ) );
collectionBinder.setOneToMany( false );
}
else if ( property.hasDirectAnnotationUsage( ManyToAny.class ) ) {
mappedBy = null;
collectionBinder.setTargetEntity( ClassDetails.VOID_CLASS_DETAILS );
collectionBinder.setCascadeStrategy( getCascadeStrategy(
null,
hibernateCascade,
false,
context
) );
collectionBinder.setCascadeStrategy(
aggregateCascadeTypes( null, hibernateCascade, false, context ) );
collectionBinder.setOneToMany( false );
}
else {
Expand Down Expand Up @@ -807,8 +748,8 @@ private void setInsertable(boolean insertable) {
this.insertable = insertable;
}

private void setCascadeStrategy(String cascadeStrategy) {
this.cascadeStrategy = cascadeStrategy;
private void setCascadeStrategy(EnumSet<CascadeType> cascadeTypes) {
this.cascadeTypes = cascadeTypes;
}

private void setAccessType(AccessType accessType) {
Expand Down Expand Up @@ -1267,8 +1208,8 @@ private void bindProperty() {
PropertyBinder binder = new PropertyBinder();
binder.setName( propertyName );
binder.setValue( collection );
binder.setCascade( cascadeStrategy );
if ( cascadeStrategy != null && cascadeStrategy.contains( "delete-orphan" ) ) {
binder.setCascade( cascadeTypes );
if ( cascadeTypes != null && cascadeTypes.contains( DELETE_ORPHAN ) ) {
collection.setOrphanDelete( true );
}
binder.setLazy( collection.isLazy() );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@
*/
package org.hibernate.boot.model.internal;

import java.util.EnumSet;
import java.util.Map;

import org.hibernate.AnnotationException;
import org.hibernate.MappingException;
import org.hibernate.annotations.CascadeType;
import org.hibernate.annotations.LazyGroup;
import org.hibernate.annotations.NotFoundAction;
import org.hibernate.annotations.OnDeleteAction;
Expand All @@ -23,6 +25,7 @@
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Property;
import org.hibernate.mapping.SortableValue;
import org.hibernate.mapping.Value;
import org.hibernate.models.spi.MemberDetails;
import org.hibernate.type.ForeignKeyDirection;

Expand All @@ -49,7 +52,7 @@ public class OneToOneSecondPass implements SecondPass {
private final NotFoundAction notFoundAction;
private final OnDeleteAction onDeleteAction;
private final boolean optional;
private final String cascadeStrategy;
private final EnumSet<CascadeType> cascadeStrategy;
private final AnnotatedJoinColumns joinColumns;
private final MetadataBuildingContext buildingContext;
private final String referencedEntityName;
Expand All @@ -65,7 +68,7 @@ public OneToOneSecondPass(
NotFoundAction notFoundAction,
OnDeleteAction onDeleteAction,
boolean optional,
String cascadeStrategy,
EnumSet<CascadeType> cascadeStrategy,
AnnotatedJoinColumns columns,
MetadataBuildingContext buildingContext) {
this.ownerEntity = ownerEntity;
Expand All @@ -84,11 +87,9 @@ public OneToOneSecondPass(

@Override
public void doSecondPass(Map<String, PersistentClass> persistentClasses) throws MappingException {
final OneToOne value = new OneToOne(
buildingContext,
propertyHolder.getTable(),
propertyHolder.getPersistentClass()
);
final OneToOne value =
new OneToOne( buildingContext, propertyHolder.getTable(),
propertyHolder.getPersistentClass() );
final String propertyName = inferredData.getPropertyName();
value.setPropertyName( propertyName );
value.setReferencedEntityName( referencedEntityName );
Expand All @@ -100,7 +101,9 @@ public void doSecondPass(Map<String, PersistentClass> persistentClasses) throws

value.setConstrained( !optional );
value.setForeignKeyType( getForeignKeyDirection() );
bindForeignKeyNameAndDefinition( value, property, property.getDirectAnnotationUsage( ForeignKey.class ), buildingContext );
bindForeignKeyNameAndDefinition( value, property,
property.getDirectAnnotationUsage( ForeignKey.class ),
buildingContext );

final PropertyBinder binder = new PropertyBinder();
binder.setName( propertyName );
Expand Down Expand Up @@ -144,10 +147,11 @@ private void bindUnowned(Map<String, PersistentClass> persistentClasses, OneToOn
+ "' targets the type '" + targetEntityName + "'" + problem );
}
final Property targetProperty = targetProperty( oneToOne, targetEntity );
if ( targetProperty.getValue() instanceof OneToOne ) {
final Value targetPropertyValue = targetProperty.getValue();
if ( targetPropertyValue instanceof OneToOne ) {
propertyHolder.addProperty( property, inferredData.getAttributeMember(), inferredData.getDeclaringClass() );
}
else if ( targetProperty.getValue() instanceof ManyToOne ) {
else if ( targetPropertyValue instanceof ManyToOne ) {
bindTargetManyToOne( persistentClasses, oneToOne, property, targetEntity, targetProperty );
}
else {
Expand All @@ -158,7 +162,7 @@ else if ( targetProperty.getValue() instanceof ManyToOne ) {
}
checkMappedByType(
mappedBy,
targetProperty.getValue(),
targetPropertyValue,
oneToOne.getPropertyName(),
propertyHolder,
persistentClasses
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import org.hibernate.MappingException;
import org.hibernate.annotations.Any;
import org.hibernate.annotations.AttributeBinderType;
import org.hibernate.annotations.CascadeType;
import org.hibernate.annotations.CompositeType;
import org.hibernate.annotations.IdGeneratorType;
import org.hibernate.annotations.Immutable;
Expand Down Expand Up @@ -122,7 +123,7 @@ public class PropertyBinder {
private Component componentElement;
private boolean insertable = true;
private boolean updatable = true;
private String cascade;
private EnumSet<CascadeType> cascadeTypes;
private BasicValueBinder basicValueBinder;
private ClassDetails declaringClass;
private boolean declaringClassSet;
Expand Down Expand Up @@ -199,8 +200,8 @@ private void setComponentElement(Component componentElement) {
this.componentElement = componentElement;
}

public void setCascade(String cascadeStrategy) {
this.cascade = cascadeStrategy;
public void setCascade(EnumSet<CascadeType> cascadeTypes) {
this.cascadeTypes = cascadeTypes;
}

public void setBuildingContext(MetadataBuildingContext buildingContext) {
Expand Down Expand Up @@ -438,7 +439,7 @@ public Property makeProperty() {
property.setValue( value );
property.setLazy( lazy );
property.setLazyGroup( lazyGroup );
property.setCascade( cascade );
property.setCascade( cascadeTypes );
property.setPropertyAccessorName( accessType.getType() );
property.setReturnedClassName( returnedClassName );
// property.setPropertyAccessStrategy( propertyAccessStrategy );
Expand Down
Loading
Loading