From a54f750152b45017828276cd6f07c2880d6cf2b0 Mon Sep 17 00:00:00 2001 From: brmeyer Date: Thu, 29 Nov 2012 16:22:50 -0500 Subject: [PATCH] HHH-7837 Support Hibernate's @Cascade annotation in metamodel --- ...ToAnyPluralAttributeElementSourceImpl.java | 6 +- ...oManyPluralAttributeElementSourceImpl.java | 2 +- ...oManyPluralAttributeElementSourceImpl.java | 7 ++- .../annotations/ToOneAttributeSourceImpl.java | 1 + .../attribute/AssociationAttribute.java | 27 ++++++++ .../util/EnumConversionHelper.java | 63 ++++++++++++++++--- .../MultiCircleNonJpaCascadeIdentityTest.java | 8 +-- .../MultiCircleNonJpaCascadeSequenceTest.java | 8 +-- 8 files changed, 99 insertions(+), 23 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/ManyToAnyPluralAttributeElementSourceImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/ManyToAnyPluralAttributeElementSourceImpl.java index 2eac143ae6..5a3a8a3fdc 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/ManyToAnyPluralAttributeElementSourceImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/ManyToAnyPluralAttributeElementSourceImpl.java @@ -17,7 +17,11 @@ public class ManyToAnyPluralAttributeElementSourceImpl implements ManyToAnyPlura @Override public Iterable getCascadeStyles() { - return EnumConversionHelper.cascadeTypeToCascadeStyleSet( attribute.getCascadeTypes(), attribute.getContext() ); + + return EnumConversionHelper.cascadeTypeToCascadeStyleSet( + attribute.getCascadeTypes(), + attribute.getHibernateCascadeTypes(), + attribute.getContext() ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/ManyToManyPluralAttributeElementSourceImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/ManyToManyPluralAttributeElementSourceImpl.java index ccb837e76a..fcbcf0f2ca 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/ManyToManyPluralAttributeElementSourceImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/ManyToManyPluralAttributeElementSourceImpl.java @@ -34,7 +34,6 @@ import org.hibernate.metamodel.internal.source.annotations.attribute.PluralAssoc import org.hibernate.metamodel.internal.source.annotations.util.EnumConversionHelper; import org.hibernate.metamodel.internal.source.annotations.util.JPADotNames; import org.hibernate.metamodel.internal.source.annotations.util.JandexHelper; -import org.hibernate.metamodel.spi.binding.CascadeType; import org.hibernate.metamodel.spi.relational.Value; import org.hibernate.metamodel.spi.source.ForeignKeyContributingSource; import org.hibernate.metamodel.spi.source.ManyToManyPluralAttributeElementSource; @@ -71,6 +70,7 @@ public class ManyToManyPluralAttributeElementSourceImpl implements ManyToManyPlu cascadeStyles = EnumConversionHelper.cascadeTypeToCascadeStyleSet( associationAttribute.getCascadeTypes(), + associationAttribute.getHibernateCascadeTypes(), associationAttribute.getContext() ); } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/OneToManyPluralAttributeElementSourceImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/OneToManyPluralAttributeElementSourceImpl.java index 80876bf47e..612fd277c7 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/OneToManyPluralAttributeElementSourceImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/OneToManyPluralAttributeElementSourceImpl.java @@ -23,8 +23,6 @@ */ package org.hibernate.metamodel.internal.source.annotations; -import java.util.Collections; - import org.hibernate.AssertionFailure; import org.hibernate.engine.spi.CascadeStyle; import org.hibernate.metamodel.internal.source.annotations.attribute.PluralAssociationAttribute; @@ -53,7 +51,10 @@ public class OneToManyPluralAttributeElementSourceImpl implements OneToManyPlura @Override public Iterable getCascadeStyles() { - return EnumConversionHelper.cascadeTypeToCascadeStyleSet( associationAttribute.getCascadeTypes(), associationAttribute.getContext() ); + return EnumConversionHelper.cascadeTypeToCascadeStyleSet( + associationAttribute.getCascadeTypes(), + associationAttribute.getHibernateCascadeTypes(), + associationAttribute.getContext() ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/ToOneAttributeSourceImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/ToOneAttributeSourceImpl.java index f484a16920..0ff09ca47f 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/ToOneAttributeSourceImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/ToOneAttributeSourceImpl.java @@ -59,6 +59,7 @@ public class ToOneAttributeSourceImpl extends SingularAttributeSourceImpl implem this.associationAttribute = associationAttribute; this.cascadeStyles = EnumConversionHelper.cascadeTypeToCascadeStyleSet( associationAttribute.getCascadeTypes(), + associationAttribute.getHibernateCascadeTypes(), associationAttribute.getContext() ); } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/AssociationAttribute.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/AssociationAttribute.java index 2858a88c0d..c0548dcd69 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/AssociationAttribute.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/AssociationAttribute.java @@ -58,6 +58,7 @@ import org.hibernate.metamodel.spi.source.MappingException; * Represents an association attribute. * * @author Hardy Ferentschik + * @author Brett Meyer */ public class AssociationAttribute extends MappedAttribute { private static final CoreMessageLogger coreLogger = Logger.getMessageLogger( @@ -69,6 +70,7 @@ public class AssociationAttribute extends MappedAttribute { private final String referencedEntityType; private final String mappedBy; private final Set cascadeTypes; + private final Set hibernateCascadeTypes; private final boolean isOptional; private final boolean isLazy; private final boolean isUnWrapProxy; @@ -122,6 +124,7 @@ public class AssociationAttribute extends MappedAttribute { this.isUnWrapProxy = determinIsUnwrapProxy(); this.isOrphanRemoval = determineOrphanRemoval( associationAnnotation ); this.cascadeTypes = determineCascadeTypes( associationAnnotation ); + this.hibernateCascadeTypes = determineHibernateCascadeTypes( annotations ); this.joinColumnValues = determineJoinColumnAnnotations( annotations ); this.fetchStyle = determineFetchStyle(); @@ -147,6 +150,10 @@ public class AssociationAttribute extends MappedAttribute { return cascadeTypes; } + public Set getHibernateCascadeTypes() { + return hibernateCascadeTypes; + } + public boolean isOrphanRemoval() { return isOrphanRemoval; } @@ -354,6 +361,26 @@ public class AssociationAttribute extends MappedAttribute { return cascadeTypes; } + private Set determineHibernateCascadeTypes( + Map> annotations) { + AnnotationInstance cascadeAnnotation = JandexHelper + .getSingleAnnotation( + annotations, HibernateDotNames.CASCADE ); + Set cascadeTypes + = new HashSet(); + if ( cascadeAnnotation != null ) { + AnnotationValue cascadeValue = cascadeAnnotation.value(); + if ( cascadeValue != null ) { + String[] cascades = cascadeValue.asEnumArray(); + for ( String s : cascades ) { + cascadeTypes.add( Enum.valueOf( + org.hibernate.annotations.CascadeType.class, s ) ); + } + } + } + return cascadeTypes; + } + private FetchStyle determineFetchStyle() { AnnotationInstance fetchAnnotation = JandexHelper.getSingleAnnotation( annotations(), HibernateDotNames.FETCH ); if ( fetchAnnotation != null ) { diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/util/EnumConversionHelper.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/util/EnumConversionHelper.java index 9ef85b8e39..7f177253ef 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/util/EnumConversionHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/util/EnumConversionHelper.java @@ -42,6 +42,7 @@ import org.hibernate.metamodel.internal.source.annotations.entity.EntityBindingC * Helper class which converts between different enum types. * * @author Hardy Ferentschik + * @author Brett Meyer */ public class EnumConversionHelper { private EnumConversionHelper() { @@ -92,6 +93,45 @@ public class EnumConversionHelper { } } } + + public static CascadeStyle cascadeTypeToCascadeStyle( + org.hibernate.annotations.CascadeType cascadeType) { + switch ( cascadeType ) { + case ALL: { + return CascadeStyles.ALL; + } + case PERSIST: { + return CascadeStyles.PERSIST; + } + case MERGE: { + return CascadeStyles.MERGE; + } + case REMOVE: { + return CascadeStyles.DELETE; + } + case REFRESH: { + return CascadeStyles.REFRESH; + } + case DETACH: { + return CascadeStyles.EVICT; + } + case DELETE: { + return CascadeStyles.DELETE; + } + case SAVE_UPDATE: { + return CascadeStyles.UPDATE; + } + case REPLICATE: { + return CascadeStyles.REPLICATE; + } + case LOCK: { + return CascadeStyles.LOCK; + } + default: { + throw new AssertionFailure( "Unknown cascade type" ); + } + } + } public static FetchMode annotationFetchModeToHibernateFetchMode(org.hibernate.annotations.FetchMode annotationFetchMode) { switch ( annotationFetchMode ) { @@ -129,18 +169,25 @@ public class EnumConversionHelper { } } - public static Set cascadeTypeToCascadeStyleSet(Set cascadeTypes, EntityBindingContext context) { - if ( CollectionHelper.isEmpty( cascadeTypes ) ) { - final Set cascadeStyles = new HashSet(); + public static Set cascadeTypeToCascadeStyleSet( + Set cascadeTypes, + Set hibernateCascadeTypes, + EntityBindingContext context) { + Set cascadeStyleSet = new HashSet(); + if ( CollectionHelper.isEmpty( cascadeTypes ) + && CollectionHelper.isEmpty( hibernateCascadeTypes ) ) { String cascades = context.getMappingDefaults().getCascadeStyle(); for ( String cascade : StringHelper.split( ",", cascades ) ) { - cascadeStyles.add( CascadeStyles.getCascadeStyle( cascade ) ); + cascadeStyleSet.add( CascadeStyles.getCascadeStyle( cascade ) ); } - return cascadeStyles; } - Set cascadeStyleSet = new HashSet(); - for ( CascadeType cascadeType : cascadeTypes ) { - cascadeStyleSet.add( cascadeTypeToCascadeStyle( cascadeType ) ); + else { + for ( CascadeType cascadeType : cascadeTypes ) { + cascadeStyleSet.add( cascadeTypeToCascadeStyle( cascadeType ) ); + } + for ( org.hibernate.annotations.CascadeType cascadeType : hibernateCascadeTypes ) { + cascadeStyleSet.add( cascadeTypeToCascadeStyle( cascadeType ) ); + } } return cascadeStyleSet; } diff --git a/hibernate-core/src/test/java/org/hibernate/test/annotations/cascade/multicircle/nonjpa/identity/MultiCircleNonJpaCascadeIdentityTest.java b/hibernate-core/src/test/java/org/hibernate/test/annotations/cascade/multicircle/nonjpa/identity/MultiCircleNonJpaCascadeIdentityTest.java index bafb6b3414..ff1e41bc32 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/annotations/cascade/multicircle/nonjpa/identity/MultiCircleNonJpaCascadeIdentityTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/annotations/cascade/multicircle/nonjpa/identity/MultiCircleNonJpaCascadeIdentityTest.java @@ -24,15 +24,14 @@ package org.hibernate.test.annotations.cascade.multicircle.nonjpa.identity; import junit.framework.Assert; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; import org.hibernate.Session; import org.hibernate.testing.DialectChecks; -import org.hibernate.testing.FailureExpectedWithNewMetamodel; import org.hibernate.testing.RequiresDialectFeature; import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; /** * This test uses a complicated model that requires Hibernate to delay @@ -83,7 +82,6 @@ import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; * c, e, d, b, g, f. */ @RequiresDialectFeature(DialectChecks.SupportsIdentityColumns.class) -@FailureExpectedWithNewMetamodel public class MultiCircleNonJpaCascadeIdentityTest extends BaseCoreFunctionalTestCase { private B b; private C c; diff --git a/hibernate-core/src/test/java/org/hibernate/test/annotations/cascade/multicircle/nonjpa/sequence/MultiCircleNonJpaCascadeSequenceTest.java b/hibernate-core/src/test/java/org/hibernate/test/annotations/cascade/multicircle/nonjpa/sequence/MultiCircleNonJpaCascadeSequenceTest.java index 4089aa11a2..711eb183ac 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/annotations/cascade/multicircle/nonjpa/sequence/MultiCircleNonJpaCascadeSequenceTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/annotations/cascade/multicircle/nonjpa/sequence/MultiCircleNonJpaCascadeSequenceTest.java @@ -24,14 +24,13 @@ package org.hibernate.test.annotations.cascade.multicircle.nonjpa.sequence; import junit.framework.Assert; + +import org.hibernate.Session; +import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; import org.junit.After; import org.junit.Before; import org.junit.Test; -import org.hibernate.Session; -import org.hibernate.testing.FailureExpectedWithNewMetamodel; -import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; - /** * This test uses a complicated model that requires Hibernate to delay * inserts until non-nullable transient entity dependencies are resolved. @@ -80,7 +79,6 @@ import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; * Entities are inserted in the following order: * c, e, d, b, g, f. */ -@FailureExpectedWithNewMetamodel public class MultiCircleNonJpaCascadeSequenceTest extends BaseCoreFunctionalTestCase { private B b; private C c;