HHH-4657 add support for DETACH
git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@18191 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
parent
49bc0e7acf
commit
ba3639a25a
|
@ -37,5 +37,8 @@ public enum CascadeType {
|
|||
REPLICATE,
|
||||
DELETE_ORPHAN,
|
||||
LOCK,
|
||||
EVICT
|
||||
/** @deprecated use DETACH */
|
||||
@Deprecated
|
||||
EVICT,
|
||||
DETACH
|
||||
}
|
||||
|
|
|
@ -2518,6 +2518,9 @@ public final class AnnotationBinder {
|
|||
case REFRESH:
|
||||
hibernateCascadeSet.add( CascadeType.REFRESH );
|
||||
break;
|
||||
case DETACH:
|
||||
hibernateCascadeSet.add( CascadeType.DETACH );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2565,6 +2568,7 @@ public final class AnnotationBinder {
|
|||
cascade.append( "," ).append( "replicate" );
|
||||
break;
|
||||
case EVICT:
|
||||
case DETACH:
|
||||
cascade.append( "," ).append( "evict" );
|
||||
break;
|
||||
case DELETE:
|
||||
|
|
|
@ -810,6 +810,7 @@ public class JPAOverridenAnnotationReader implements AnnotationReader {
|
|||
if ( subelement.element( "cascade-merge" ) != null ) cascades.add( CascadeType.MERGE );
|
||||
if ( subelement.element( "cascade-remove" ) != null ) cascades.add( CascadeType.REMOVE );
|
||||
if ( subelement.element( "cascade-refresh" ) != null ) cascades.add( CascadeType.REFRESH );
|
||||
if ( subelement.element( "cascade-detach" ) != null ) cascades.add( CascadeType.DETACH );
|
||||
}
|
||||
if ( Boolean.TRUE.equals( defaults.getCascadePersist() )
|
||||
&& !cascades.contains( CascadeType.ALL ) && !cascades.contains( CascadeType.PERSIST ) ) {
|
||||
|
|
|
@ -102,6 +102,40 @@ public class CascadeTest extends TestCase {
|
|||
s.close();
|
||||
}
|
||||
|
||||
public void testDetach() {
|
||||
Session s;
|
||||
Transaction tx;
|
||||
s = openSession();
|
||||
tx = s.beginTransaction();
|
||||
Tooth tooth = new Tooth();
|
||||
Mouth mouth = new Mouth();
|
||||
s.persist( mouth );
|
||||
s.persist( tooth );
|
||||
tooth.mouth = mouth;
|
||||
mouth.teeth = new ArrayList<Tooth>();
|
||||
mouth.teeth.add( tooth );
|
||||
tx.commit();
|
||||
s.close();
|
||||
|
||||
s = openSession();
|
||||
tx = s.beginTransaction();
|
||||
mouth = (Mouth) s.get( Mouth.class, mouth.id );
|
||||
assertNotNull( mouth );
|
||||
assertEquals( 1, mouth.teeth.size() );
|
||||
tooth = mouth.teeth.iterator().next();
|
||||
s.evict( mouth );
|
||||
assertFalse( s.contains( tooth ) );
|
||||
tx.commit();
|
||||
s.close();
|
||||
|
||||
s = openSession();
|
||||
tx = s.beginTransaction();
|
||||
s.delete( s.get( Mouth.class, mouth.id ) );
|
||||
|
||||
tx.commit();
|
||||
s.close();
|
||||
}
|
||||
|
||||
public CascadeTest(String x) {
|
||||
super( x );
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import javax.persistence.GeneratedValue;
|
|||
import javax.persistence.Id;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.Column;
|
||||
import static javax.persistence.CascadeType.*;
|
||||
|
||||
/**
|
||||
* @author Emmanuel Bernard
|
||||
|
@ -19,6 +20,6 @@ public class Mouth {
|
|||
public Integer id;
|
||||
@Column(name="mouth_size")
|
||||
public int size;
|
||||
@OneToMany(mappedBy = "mouth", cascade = CascadeType.REMOVE)
|
||||
@OneToMany(mappedBy = "mouth", cascade = { REMOVE, DETACH } )
|
||||
public Collection<Tooth> teeth;
|
||||
}
|
||||
|
|
|
@ -43,6 +43,7 @@ import javax.persistence.Query;
|
|||
import javax.persistence.TransactionRequiredException;
|
||||
import javax.persistence.TypedQuery;
|
||||
import javax.persistence.PessimisticLockScope;
|
||||
import javax.persistence.LockTimeoutException;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.metamodel.Metamodel;
|
||||
|
@ -805,6 +806,9 @@ public abstract class AbstractEntityManagerImpl implements HibernateEntityManage
|
|||
if ( e instanceof NonUniqueResultException ) {
|
||||
return;
|
||||
}
|
||||
if ( e instanceof LockTimeoutException ) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
markAsRollback();
|
||||
|
|
|
@ -31,8 +31,7 @@ public class CascadeTest extends TestCase {
|
|||
|
||||
em.persist( teacher );
|
||||
em.getTransaction().commit();
|
||||
|
||||
System.out.println("***************************");
|
||||
|
||||
em = getOrCreateEntityManager();
|
||||
em.getTransaction().begin();
|
||||
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
package org.hibernate.ejb.test.cascade;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.ArrayList;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.EntityManager;
|
||||
import static javax.persistence.CascadeType.*;
|
||||
|
||||
import org.hibernate.ejb.test.TestCase;
|
||||
|
||||
/**
|
||||
* @author Emmanuel Bernard
|
||||
*/
|
||||
public class DetachAndContainsTest extends TestCase {
|
||||
|
||||
public void testDetach() {
|
||||
EntityManager em = getOrCreateEntityManager();
|
||||
em.getTransaction().begin();
|
||||
|
||||
Tooth tooth = new Tooth();
|
||||
Mouth mouth = new Mouth();
|
||||
em.persist( mouth );
|
||||
em.persist( tooth );
|
||||
tooth.mouth = mouth;
|
||||
mouth.teeth = new ArrayList<Tooth>();
|
||||
mouth.teeth.add( tooth );
|
||||
em.getTransaction().commit();
|
||||
em.close();
|
||||
|
||||
em = getOrCreateEntityManager();
|
||||
em.getTransaction().begin();
|
||||
mouth = em.find( Mouth.class, mouth.id );
|
||||
assertNotNull( mouth );
|
||||
assertEquals( 1, mouth.teeth.size() );
|
||||
tooth = mouth.teeth.iterator().next();
|
||||
em.detach( mouth );
|
||||
assertFalse( em.contains( tooth ) );
|
||||
em.getTransaction().commit();
|
||||
em.close();
|
||||
|
||||
em = getOrCreateEntityManager();
|
||||
em.getTransaction().begin();
|
||||
em.remove( em.find( Mouth.class, mouth.id ) );
|
||||
|
||||
em.getTransaction().commit();
|
||||
em.close();
|
||||
}
|
||||
|
||||
public Class[] getAnnotatedClasses() {
|
||||
return new Class[] {
|
||||
Mouth.class,
|
||||
Tooth.class
|
||||
};
|
||||
}
|
||||
|
||||
@Entity
|
||||
public static class Mouth {
|
||||
@Id
|
||||
@GeneratedValue
|
||||
public Integer id;
|
||||
@OneToMany(mappedBy = "mouth", cascade = { DETACH, REMOVE } )
|
||||
public Collection<Tooth> teeth;
|
||||
}
|
||||
|
||||
@Entity
|
||||
public static class Tooth {
|
||||
@Id
|
||||
@GeneratedValue
|
||||
public Integer id;
|
||||
public String type;
|
||||
@ManyToOne
|
||||
public Mouth mouth;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue