Java Mailing List Archive

http://www.junlu.com/

Home » Home (12/2007) » JBoss User Help »

[jboss-user] [EJB 3.0] - CascadeType is misbehaving!

scott.stark@jboss.org

2007-03-28


I am seeing something very weird with respect to cascading. There are really two problems. Let's say that I have classes A and B, and then a main method below that:


|
| @Entity
| @Table(name="A")
| public class A {
|
|   @Column(name="ID")
|   private String id;
|  
|   @OneToMany(cascade= {CascadeType.REMOVE, CascadeType.REFRESH, CascadeType.PERSIST})
|   @JoinColumn(name="PARENT_ID")
|   private Collection<B> children;
|  
|  
|   public A() {
|      super();
|   }
|
|   public A(String id) {
|      this.id = id;
|   }
|  
|   public Collection<B> getChildren() {
|      return children;
|   }
|
|
|   public void setChildren(Collection<B> children) {
|      this.children = children;
|   }
|
|   public String getId() {
|      return id;
|   }
|
|   public void setId(String id) {
|      this.id = id;
|   }
|
| }
|


|
| @Entity
| @Table(name="B")
| public class B implements Serializable {
|
|   @Column(name="ID")
|   private String id;
|  
|   @Column(name="PARENT_ID")
|   private String parent;
|  
|   public B() {
|      super();
|   }
|      
|   public B(String id) {
|      this.id = id;
|   }
|
|   public String getId() {
|      return id;
|   }
|
|   public void setId(String id) {
|      this.id = id;
|   }
|
|   public String getParent() {
|      return parent;
|   }
|
|   public void setParent(String parent) {
|      this.parent = parent;
|   }
|
| }
|

|
| public class EJB3Test {
|
|   public static void main(String[] args) {
|      A a = new A(generateId());
|      B b = new B(generateId());
|      
|      a.setChildren(Arrays.asLis(new B[] { b }));
|      b.setParent(a.getId());
|      
|      //for argument's sake, let's just say SessionFacade is just a wrapper
|      //around EntityManager.persist/merge/remove
|      SessionFacade.persist(a);
|      
|      a = new A(a.getId());
|      
|      //let's say we've changed 'a' somehow, and we want those changes
|      //persisted, but we WANT it's relationship to it's children
|      //preserved.
|      SessionFacade.merge(a);
|   }
| }
|

The first problem:
Notice how I don't have CascadeType.MERGE set on the relationship between A and it's children. Why then, when I do the merge(), will it attempt to set B.PARENT_ID to null? I would think that if it's not set to cascade on a merge, the EntityManager shouldn't even touch children. I have found however, that setting updatable=false on the JoinColumn causes the expected behavior.

The second problem is an extension of the first:
Let's take it one step further, assuming we set updatable=false, and right before we try SessionFacade.merge(a), we do this:


| a.setChildren(Arrays.asList(new B[] { new B(someNewId) } ));
|
| //then do:
| SessionFacade.merge(a)
|

The merge now throws an exception, even though it's NOT set to cascade on merge, and children is set to updatable=false. The exception we get is an EntityNotFoundException stating that it can't find an object B with id: someNewId. Well no kidding! It's not there! I know it seems weird to NOT want to cascade, but I assure you - in my context, I simply need more control over how the children are inserted. Therefore, it makes perfect sense to have children that I do not want persisted until I explicitly do so.

I shouldn't have to grab a reference to the children, null out the field in A, and then merge all the children.

| Collection<B> children = a.getChildren();
| a.setChildren(null);
|
| SessionFacade.merge(a);
|
| for(B child : children)
|    SessionFacade.merge(child);
|

ANY help would be greatly appreciated!!! This is driving me crazy!

View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4032614#4032614

Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4032614
_______________________________________________
jboss-user mailing list
jboss-user@(protected)
https://lists.jboss.org/mailman/listinfo/jboss-user
©2008 junlu.com - Jax Systems, LLC, U.S.A.