HHH-7837 Support Hibernate's @Cascade annotation in metamodel
This commit is contained in:
parent
727e51c0e5
commit
a54f750152
|
@ -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
|
||||||
|
|
|
@ -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() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 ) {
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue