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:
Emmanuel Bernard 2009-12-10 09:32:25 +00:00
parent 49bc0e7acf
commit ba3639a25a
8 changed files with 128 additions and 4 deletions

View File

@ -37,5 +37,8 @@ public enum CascadeType {
REPLICATE,
DELETE_ORPHAN,
LOCK,
EVICT
/** @deprecated use DETACH */
@Deprecated
EVICT,
DETACH
}

View File

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

View File

@ -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 ) ) {

View File

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

View File

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

View File

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

View File

@ -31,8 +31,7 @@ public class CascadeTest extends TestCase {
em.persist( teacher );
em.getTransaction().commit();
System.out.println("***************************");
em = getOrCreateEntityManager();
em.getTransaction().begin();

View File

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