HHH-9158 - cascade-persist in orm.xml does not apply to annotation-based relationships
This commit is contained in:
parent
abb3590d33
commit
c4010d0af0
|
@ -203,11 +203,11 @@ public interface AvailableSettings {
|
|||
/**
|
||||
* Used to define how the current thread context {@link ClassLoader} must be used
|
||||
* for class lookup.
|
||||
*
|
||||
*
|
||||
* @see TcclLookupPrecedence
|
||||
*/
|
||||
String TC_CLASSLOADER = "hibernate.classLoader.tccl_lookup_precedence";
|
||||
|
||||
|
||||
/**
|
||||
* Names the {@link ClassLoader} used to load user application classes.
|
||||
* @since 4.0
|
||||
|
@ -1494,7 +1494,7 @@ public interface AvailableSettings {
|
|||
* Names the {@link org.hibernate.loader.BatchFetchStyle} to use. Can specify either the
|
||||
* {@link org.hibernate.loader.BatchFetchStyle} name (insensitively), or a
|
||||
* {@link org.hibernate.loader.BatchFetchStyle} instance.
|
||||
*
|
||||
*
|
||||
* {@code LEGACY} is the default value.
|
||||
*/
|
||||
String BATCH_FETCH_STYLE = "hibernate.batch_fetch_style";
|
||||
|
|
|
@ -91,6 +91,7 @@ public class JPAMetadataProvider implements MetadataProvider {
|
|||
defaults.put( "schema", xmlDefaults.getSchema() );
|
||||
defaults.put( "catalog", xmlDefaults.getCatalog() );
|
||||
defaults.put( "delimited-identifier", xmlDefaults.getDelimitedIdentifier() );
|
||||
defaults.put( "cascade-persist", xmlDefaults.getCascadePersist() );
|
||||
List<Class> entityListeners = new ArrayList<Class>();
|
||||
for ( String className : xmlContext.getDefaultEntityListeners() ) {
|
||||
try {
|
||||
|
|
|
@ -13,6 +13,7 @@ import java.lang.reflect.AnnotatedElement;
|
|||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
|
@ -779,6 +780,52 @@ public class JPAOverriddenAnnotationReader implements AnnotationReader {
|
|||
}
|
||||
}
|
||||
|
||||
private Annotation overridesDefaultCascadePersist(Annotation annotation, XMLContext.Default defaults) {
|
||||
if ( Boolean.TRUE.equals( defaults.getCascadePersist() ) ) {
|
||||
final Class<? extends Annotation> annotationType = annotation.annotationType();
|
||||
|
||||
if ( annotationType == ManyToOne.class ) {
|
||||
ManyToOne manyToOne = (ManyToOne) annotation;
|
||||
List<CascadeType> cascades = new ArrayList<>( Arrays.asList( manyToOne.cascade() ) );
|
||||
if ( !cascades.contains( CascadeType.ALL ) && !cascades.contains( CascadeType.PERSIST ) ) {
|
||||
cascades.add( CascadeType.PERSIST );
|
||||
}
|
||||
else {
|
||||
return annotation;
|
||||
}
|
||||
|
||||
AnnotationDescriptor ad = new AnnotationDescriptor( annotationType );
|
||||
ad.setValue( "cascade", cascades.toArray( new CascadeType[] {} ) );
|
||||
ad.setValue( "targetEntity", manyToOne.targetEntity() );
|
||||
ad.setValue( "fetch", manyToOne.fetch() );
|
||||
ad.setValue( "optional", manyToOne.optional() );
|
||||
|
||||
return AnnotationFactory.create( ad );
|
||||
}
|
||||
else if ( annotationType == OneToOne.class ) {
|
||||
OneToOne oneToOne = (OneToOne) annotation;
|
||||
List<CascadeType> cascades = new ArrayList<>( Arrays.asList( oneToOne.cascade() ) );
|
||||
if ( !cascades.contains( CascadeType.ALL ) && !cascades.contains( CascadeType.PERSIST ) ) {
|
||||
cascades.add( CascadeType.PERSIST );
|
||||
}
|
||||
else {
|
||||
return annotation;
|
||||
}
|
||||
|
||||
AnnotationDescriptor ad = new AnnotationDescriptor( annotationType );
|
||||
ad.setValue( "cascade", cascades.toArray( new CascadeType[] {} ) );
|
||||
ad.setValue( "targetEntity", oneToOne.targetEntity() );
|
||||
ad.setValue( "fetch", oneToOne.fetch() );
|
||||
ad.setValue( "optional", oneToOne.optional() );
|
||||
ad.setValue( "mappedBy", oneToOne.mappedBy() );
|
||||
ad.setValue( "orphanRemoval", oneToOne.orphanRemoval() );
|
||||
|
||||
return AnnotationFactory.create( ad );
|
||||
}
|
||||
}
|
||||
return annotation;
|
||||
}
|
||||
|
||||
private void getJoinTable(List<Annotation> annotationList, Element tree, XMLContext.Default defaults) {
|
||||
addIfNotNull( annotationList, buildJoinTable( tree, defaults ) );
|
||||
}
|
||||
|
@ -857,6 +904,7 @@ public class JPAOverriddenAnnotationReader implements AnnotationReader {
|
|||
if ( elementsForProperty.size() == 0 && defaults.canUseJavaAnnotations() ) {
|
||||
Annotation annotation = getPhysicalAnnotation( annotationType );
|
||||
if ( annotation != null ) {
|
||||
annotation = overridesDefaultCascadePersist( annotation, defaults );
|
||||
annotationList.add( annotation );
|
||||
annotation = overridesDefaultsInJoinTable( annotation, defaults );
|
||||
addIfNotNull( annotationList, annotation );
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.jpa.test.mapping;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
|
||||
|
||||
/**
|
||||
* @author Vlad Mihalcea
|
||||
*/
|
||||
public class DefaultCascadeTest extends BaseEntityManagerFunctionalTestCase {
|
||||
|
||||
@Test
|
||||
public void testCascadePersist() {
|
||||
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||
Parent parent = new Parent();
|
||||
Child child = new Child();
|
||||
child.parent = parent;
|
||||
|
||||
entityManager.persist( child );
|
||||
} );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getEjb3DD() {
|
||||
return new String[] {
|
||||
"org/hibernate/jpa/test/mapping/orm.xml"
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<?>[] getAnnotatedClasses() {
|
||||
return new Class<?>[] {
|
||||
Parent.class,
|
||||
Child.class
|
||||
};
|
||||
}
|
||||
|
||||
@Entity
|
||||
@Table(name = "Parent")
|
||||
public static class Parent {
|
||||
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private Integer id;
|
||||
}
|
||||
|
||||
@Entity
|
||||
@Table(name = "Child")
|
||||
public static class Child {
|
||||
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private Integer id;
|
||||
|
||||
@ManyToOne
|
||||
private Parent parent;
|
||||
}
|
||||
}
|
|
@ -9,6 +9,7 @@
|
|||
<persistence-unit-metadata>
|
||||
<persistence-unit-defaults>
|
||||
<delimited-identifiers/>
|
||||
<cascade-persist/>
|
||||
</persistence-unit-defaults>
|
||||
</persistence-unit-metadata>
|
||||
</entity-mappings>
|
||||
|
|
Loading…
Reference in New Issue