HHH-7837 Support Hibernate's @Cascade annotation in metamodel

This commit is contained in:
brmeyer 2012-11-29 16:22:50 -05:00
parent 727e51c0e5
commit a54f750152
8 changed files with 99 additions and 23 deletions

View File

@ -17,7 +17,11 @@ public class ManyToAnyPluralAttributeElementSourceImpl implements ManyToAnyPlura
@Override @Override
public Iterable<CascadeStyle> getCascadeStyles() { public Iterable<CascadeStyle> getCascadeStyles() {
return EnumConversionHelper.cascadeTypeToCascadeStyleSet( attribute.getCascadeTypes(), attribute.getContext() );
return EnumConversionHelper.cascadeTypeToCascadeStyleSet(
attribute.getCascadeTypes(),
attribute.getHibernateCascadeTypes(),
attribute.getContext() );
} }
@Override @Override

View File

@ -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.EnumConversionHelper;
import org.hibernate.metamodel.internal.source.annotations.util.JPADotNames; import org.hibernate.metamodel.internal.source.annotations.util.JPADotNames;
import org.hibernate.metamodel.internal.source.annotations.util.JandexHelper; 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.relational.Value;
import org.hibernate.metamodel.spi.source.ForeignKeyContributingSource; import org.hibernate.metamodel.spi.source.ForeignKeyContributingSource;
import org.hibernate.metamodel.spi.source.ManyToManyPluralAttributeElementSource; import org.hibernate.metamodel.spi.source.ManyToManyPluralAttributeElementSource;
@ -71,6 +70,7 @@ public class ManyToManyPluralAttributeElementSourceImpl implements ManyToManyPlu
cascadeStyles = EnumConversionHelper.cascadeTypeToCascadeStyleSet( cascadeStyles = EnumConversionHelper.cascadeTypeToCascadeStyleSet(
associationAttribute.getCascadeTypes(), associationAttribute.getCascadeTypes(),
associationAttribute.getHibernateCascadeTypes(),
associationAttribute.getContext() ); associationAttribute.getContext() );
} }

View File

@ -23,8 +23,6 @@
*/ */
package org.hibernate.metamodel.internal.source.annotations; package org.hibernate.metamodel.internal.source.annotations;
import java.util.Collections;
import org.hibernate.AssertionFailure; import org.hibernate.AssertionFailure;
import org.hibernate.engine.spi.CascadeStyle; import org.hibernate.engine.spi.CascadeStyle;
import org.hibernate.metamodel.internal.source.annotations.attribute.PluralAssociationAttribute; import org.hibernate.metamodel.internal.source.annotations.attribute.PluralAssociationAttribute;
@ -53,7 +51,10 @@ public class OneToManyPluralAttributeElementSourceImpl implements OneToManyPlura
@Override @Override
public Iterable<CascadeStyle> getCascadeStyles() { public Iterable<CascadeStyle> getCascadeStyles() {
return EnumConversionHelper.cascadeTypeToCascadeStyleSet( associationAttribute.getCascadeTypes(), associationAttribute.getContext() ); return EnumConversionHelper.cascadeTypeToCascadeStyleSet(
associationAttribute.getCascadeTypes(),
associationAttribute.getHibernateCascadeTypes(),
associationAttribute.getContext() );
} }
@Override @Override

View File

@ -59,6 +59,7 @@ public class ToOneAttributeSourceImpl extends SingularAttributeSourceImpl implem
this.associationAttribute = associationAttribute; this.associationAttribute = associationAttribute;
this.cascadeStyles = EnumConversionHelper.cascadeTypeToCascadeStyleSet( this.cascadeStyles = EnumConversionHelper.cascadeTypeToCascadeStyleSet(
associationAttribute.getCascadeTypes(), associationAttribute.getCascadeTypes(),
associationAttribute.getHibernateCascadeTypes(),
associationAttribute.getContext() associationAttribute.getContext()
); );
} }

View File

@ -58,6 +58,7 @@ import org.hibernate.metamodel.spi.source.MappingException;
* Represents an association attribute. * Represents an association attribute.
* *
* @author Hardy Ferentschik * @author Hardy Ferentschik
* @author Brett Meyer
*/ */
public class AssociationAttribute extends MappedAttribute { public class AssociationAttribute extends MappedAttribute {
private static final CoreMessageLogger coreLogger = Logger.getMessageLogger( private static final CoreMessageLogger coreLogger = Logger.getMessageLogger(
@ -69,6 +70,7 @@ public class AssociationAttribute extends MappedAttribute {
private final String referencedEntityType; private final String referencedEntityType;
private final String mappedBy; private final String mappedBy;
private final Set<CascadeType> cascadeTypes; private final Set<CascadeType> cascadeTypes;
private final Set<org.hibernate.annotations.CascadeType> hibernateCascadeTypes;
private final boolean isOptional; private final boolean isOptional;
private final boolean isLazy; private final boolean isLazy;
private final boolean isUnWrapProxy; private final boolean isUnWrapProxy;
@ -122,6 +124,7 @@ public class AssociationAttribute extends MappedAttribute {
this.isUnWrapProxy = determinIsUnwrapProxy(); this.isUnWrapProxy = determinIsUnwrapProxy();
this.isOrphanRemoval = determineOrphanRemoval( associationAnnotation ); this.isOrphanRemoval = determineOrphanRemoval( associationAnnotation );
this.cascadeTypes = determineCascadeTypes( associationAnnotation ); this.cascadeTypes = determineCascadeTypes( associationAnnotation );
this.hibernateCascadeTypes = determineHibernateCascadeTypes( annotations );
this.joinColumnValues = determineJoinColumnAnnotations( annotations ); this.joinColumnValues = determineJoinColumnAnnotations( annotations );
this.fetchStyle = determineFetchStyle(); this.fetchStyle = determineFetchStyle();
@ -147,6 +150,10 @@ public class AssociationAttribute extends MappedAttribute {
return cascadeTypes; return cascadeTypes;
} }
public Set<org.hibernate.annotations.CascadeType> getHibernateCascadeTypes() {
return hibernateCascadeTypes;
}
public boolean isOrphanRemoval() { public boolean isOrphanRemoval() {
return isOrphanRemoval; return isOrphanRemoval;
} }
@ -354,6 +361,26 @@ public class AssociationAttribute extends MappedAttribute {
return cascadeTypes; return cascadeTypes;
} }
private Set<org.hibernate.annotations.CascadeType> determineHibernateCascadeTypes(
Map<DotName, List<AnnotationInstance>> annotations) {
AnnotationInstance cascadeAnnotation = JandexHelper
.getSingleAnnotation(
annotations, HibernateDotNames.CASCADE );
Set<org.hibernate.annotations.CascadeType> cascadeTypes
= new HashSet<org.hibernate.annotations.CascadeType>();
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() { private FetchStyle determineFetchStyle() {
AnnotationInstance fetchAnnotation = JandexHelper.getSingleAnnotation( annotations(), HibernateDotNames.FETCH ); AnnotationInstance fetchAnnotation = JandexHelper.getSingleAnnotation( annotations(), HibernateDotNames.FETCH );
if ( fetchAnnotation != null ) { if ( fetchAnnotation != null ) {

View File

@ -42,6 +42,7 @@ import org.hibernate.metamodel.internal.source.annotations.entity.EntityBindingC
* Helper class which converts between different enum types. * Helper class which converts between different enum types.
* *
* @author Hardy Ferentschik * @author Hardy Ferentschik
* @author Brett Meyer
*/ */
public class EnumConversionHelper { public class EnumConversionHelper {
private 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) { public static FetchMode annotationFetchModeToHibernateFetchMode(org.hibernate.annotations.FetchMode annotationFetchMode) {
switch ( annotationFetchMode ) { switch ( annotationFetchMode ) {
@ -129,18 +169,25 @@ public class EnumConversionHelper {
} }
} }
public static Set<CascadeStyle> cascadeTypeToCascadeStyleSet(Set<CascadeType> cascadeTypes, EntityBindingContext context) { public static Set<CascadeStyle> cascadeTypeToCascadeStyleSet(
if ( CollectionHelper.isEmpty( cascadeTypes ) ) { Set<CascadeType> cascadeTypes,
final Set<CascadeStyle> cascadeStyles = new HashSet<CascadeStyle>(); Set<org.hibernate.annotations.CascadeType> hibernateCascadeTypes,
EntityBindingContext context) {
Set<CascadeStyle> cascadeStyleSet = new HashSet<CascadeStyle>();
if ( CollectionHelper.isEmpty( cascadeTypes )
&& CollectionHelper.isEmpty( hibernateCascadeTypes ) ) {
String cascades = context.getMappingDefaults().getCascadeStyle(); String cascades = context.getMappingDefaults().getCascadeStyle();
for ( String cascade : StringHelper.split( ",", cascades ) ) { for ( String cascade : StringHelper.split( ",", cascades ) ) {
cascadeStyles.add( CascadeStyles.getCascadeStyle( cascade ) ); cascadeStyleSet.add( CascadeStyles.getCascadeStyle( cascade ) );
} }
return cascadeStyles;
} }
Set<CascadeStyle> cascadeStyleSet = new HashSet<CascadeStyle>(); else {
for ( CascadeType cascadeType : cascadeTypes ) { for ( CascadeType cascadeType : cascadeTypes ) {
cascadeStyleSet.add( cascadeTypeToCascadeStyle( cascadeType ) ); cascadeStyleSet.add( cascadeTypeToCascadeStyle( cascadeType ) );
}
for ( org.hibernate.annotations.CascadeType cascadeType : hibernateCascadeTypes ) {
cascadeStyleSet.add( cascadeTypeToCascadeStyle( cascadeType ) );
}
} }
return cascadeStyleSet; return cascadeStyleSet;
} }

View File

@ -24,15 +24,14 @@
package org.hibernate.test.annotations.cascade.multicircle.nonjpa.identity; package org.hibernate.test.annotations.cascade.multicircle.nonjpa.identity;
import junit.framework.Assert; import junit.framework.Assert;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.hibernate.Session; import org.hibernate.Session;
import org.hibernate.testing.DialectChecks; import org.hibernate.testing.DialectChecks;
import org.hibernate.testing.FailureExpectedWithNewMetamodel;
import org.hibernate.testing.RequiresDialectFeature; import org.hibernate.testing.RequiresDialectFeature;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; 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 * 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. * c, e, d, b, g, f.
*/ */
@RequiresDialectFeature(DialectChecks.SupportsIdentityColumns.class) @RequiresDialectFeature(DialectChecks.SupportsIdentityColumns.class)
@FailureExpectedWithNewMetamodel
public class MultiCircleNonJpaCascadeIdentityTest extends BaseCoreFunctionalTestCase { public class MultiCircleNonJpaCascadeIdentityTest extends BaseCoreFunctionalTestCase {
private B b; private B b;
private C c; private C c;

View File

@ -24,14 +24,13 @@
package org.hibernate.test.annotations.cascade.multicircle.nonjpa.sequence; package org.hibernate.test.annotations.cascade.multicircle.nonjpa.sequence;
import junit.framework.Assert; import junit.framework.Assert;
import org.hibernate.Session;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; 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 * This test uses a complicated model that requires Hibernate to delay
* inserts until non-nullable transient entity dependencies are resolved. * 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: * Entities are inserted in the following order:
* c, e, d, b, g, f. * c, e, d, b, g, f.
*/ */
@FailureExpectedWithNewMetamodel
public class MultiCircleNonJpaCascadeSequenceTest extends BaseCoreFunctionalTestCase { public class MultiCircleNonJpaCascadeSequenceTest extends BaseCoreFunctionalTestCase {
private B b; private B b;
private C c; private C c;