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
public Iterable<CascadeStyle> getCascadeStyles() {
return EnumConversionHelper.cascadeTypeToCascadeStyleSet( attribute.getCascadeTypes(), attribute.getContext() );
return EnumConversionHelper.cascadeTypeToCascadeStyleSet(
attribute.getCascadeTypes(),
attribute.getHibernateCascadeTypes(),
attribute.getContext() );
}
@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.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() );
}

View File

@ -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<CascadeStyle> getCascadeStyles() {
return EnumConversionHelper.cascadeTypeToCascadeStyleSet( associationAttribute.getCascadeTypes(), associationAttribute.getContext() );
return EnumConversionHelper.cascadeTypeToCascadeStyleSet(
associationAttribute.getCascadeTypes(),
associationAttribute.getHibernateCascadeTypes(),
associationAttribute.getContext() );
}
@Override

View File

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

View File

@ -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<CascadeType> cascadeTypes;
private final Set<org.hibernate.annotations.CascadeType> 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<org.hibernate.annotations.CascadeType> getHibernateCascadeTypes() {
return hibernateCascadeTypes;
}
public boolean isOrphanRemoval() {
return isOrphanRemoval;
}
@ -354,6 +361,26 @@ public class AssociationAttribute extends MappedAttribute {
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() {
AnnotationInstance fetchAnnotation = JandexHelper.getSingleAnnotation( annotations(), HibernateDotNames.FETCH );
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.
*
* @author Hardy Ferentschik
* @author Brett Meyer
*/
public class EnumConversionHelper {
private EnumConversionHelper() {
@ -93,6 +94,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 ) {
case JOIN: {
@ -129,19 +169,26 @@ public class EnumConversionHelper {
}
}
public static Set<CascadeStyle> cascadeTypeToCascadeStyleSet(Set<CascadeType> cascadeTypes, EntityBindingContext context) {
if ( CollectionHelper.isEmpty( cascadeTypes ) ) {
final Set<CascadeStyle> cascadeStyles = new HashSet<CascadeStyle>();
public static Set<CascadeStyle> cascadeTypeToCascadeStyleSet(
Set<CascadeType> cascadeTypes,
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();
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 ) {
cascadeStyleSet.add( cascadeTypeToCascadeStyle( cascadeType ) );
}
for ( org.hibernate.annotations.CascadeType cascadeType : hibernateCascadeTypes ) {
cascadeStyleSet.add( cascadeTypeToCascadeStyle( cascadeType ) );
}
}
return cascadeStyleSet;
}
}

View File

@ -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;

View File

@ -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;