-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 7 posts ] 
Author Message
 Post subject: OneToMany: list childs is null in prepersist method
PostPosted: Thu Apr 24, 2008 10:17 am 
Newbie

Joined: Thu Apr 24, 2008 9:33 am
Posts: 3
Hibernate version: 3.2.6.ga
Hibernate entitymanager version: 3.3.1.ga
Hibernate annotations version: 3.3.0.ga
Mapping documents:

Hello everybody,

Here is my problem :
I have 2 entities : Parent and Child with a OneToMany (bi-directional)
In the parent class i declare a @PrePersist callback method that throw an RunTimeException when the number of childs is little than 2 or if the reference of the list is null.

In a testng class, I create a new object Parent and add it 2 childs[/b].
When I execute em.merge on the parent, the runtime exception is throwed by the PrePersist callback method.
=> the reference of the childs' list is null !!.

My question : "Is It normal ?"

Here is the Parent class :
Code:
package be.philou.test;

import java.io.Serializable;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.PrePersist;
import javax.persistence.PreUpdate;

@Entity
public class Parent implements Serializable {
   
   private static final long serialVersionUID = 4076893988337190107L;
   
   private int id;
   private String name;
   private String firstName;

   private List<Child> childs;
   
   // -------------------------------------------------------------------------
   // getters & setters
   // -------------------------------------------------------------------------
   
   @Id
   public int getId() {
      return id;
   }
   public void setId(int id) {
      this.id = id;
   }

   public String getName() {
      return name;
   }
   public void setName(String name) {
      this.name = name;
   }

   public String getFirstName() {
      return firstName;
   }
   public void setFirstName(String firstName) {
      this.firstName = firstName;
   }

   @OneToMany(mappedBy="parent", cascade=CascadeType.ALL)
   public List<Child> getChilds() {
      return childs;
   }
   public void setChilds(List<Child> childs) {
      this.childs = childs;
   }

   // -------------------------------------------------------------------------
   // callbacks
   // -------------------------------------------------------------------------

   @PrePersist
   @PreUpdate
   public void beforeCreate() {
      // Parent must have minimum 2 childs
      if (getChilds() == null || getChilds().size() < 2) {
         throw new RuntimeException("Parent must have minimum 2 childs");
      }
   }
   
}



Here is the Child class :
Code:
package be.philou.test;

import java.io.Serializable;

import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;

@Entity
public class Child implements Serializable {
   private static final long serialVersionUID = 5120375761727811864L;
   
   private int id;
   private String info;
   
   private Parent parent;

   // -------------------------------------------------------------------------
   // getters & setters
   // -------------------------------------------------------------------------
   
   @Id
   public int getId() {
      return id;
   }
   public void setId(int id) {
      this.id = id;
   }

   public String getInfo() {
      return info;
   }
   public void setInfo(String info) {
      this.info = info;
   }

   @ManyToOne
   @JoinColumn(name="FK_PARENT")
   public Parent getParent() {
      return parent;
   }
   public void setParent(Parent parent) {
      this.parent = parent;
   }
   
   
}



Top
 Profile  
 
 Post subject:
PostPosted: Mon Apr 28, 2008 3:49 pm 
Hibernate Team
Hibernate Team

Joined: Thu Apr 05, 2007 5:52 am
Posts: 1689
Location: Sweden
Hi,

I am not quite sure where the problem is, but maybe it would help if you would post your test code?

--Hardy


Top
 Profile  
 
 Post subject:
PostPosted: Wed Apr 30, 2008 5:59 am 
Newbie

Joined: Thu Apr 24, 2008 9:33 am
Posts: 3
Hi Hardy and thanks for your reply,

here is the test code
Note: the parentmanager.merge() simply call the em.merge() method

Code:
package be.philou.test;

import java.util.ArrayList;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.testng.AbstractTestNGSpringContextTests;
import org.testng.annotations.Test;

@ContextConfiguration(locations={"/spring-config.xml"})
@Test
public class ParentTest extends AbstractTestNGSpringContextTests {
   
   @Autowired private ParentManager parentManager;
   
   public void parentCreate() {
      Parent parent = new Parent();
      parent.setFirstName("firstName");
      parent.setName("name");
      parent.setChilds(new ArrayList<Child>());
      
      Child child;
      child = new Child();
      child.setInfo("child1");
      parent.getChilds().add(child);
      child.setParent(parent);
      
      child = new Child();
      child.setInfo("child2");
      parent.getChilds().add(child);
      child.setParent(parent);
      
      System.out.println("Childs count = " + parent.getChilds().size());
      parent = parentManager.merge(parent);
   }
   
}


Top
 Profile  
 
 Post subject:
PostPosted: Wed Apr 30, 2008 9:40 am 
Hibernate Team
Hibernate Team

Joined: Thu Apr 05, 2007 5:52 am
Posts: 1689
Location: Sweden
Hmm, I am not sure what goes wrong here. I assume your are using EntityManager.merge()? Have you tried using persist instead? You could also enable sql output to see if and which statements get executed.

--Hardy


Top
 Profile  
 
 Post subject:
PostPosted: Wed May 07, 2008 3:27 pm 
Newbie

Joined: Thu Apr 24, 2008 9:33 am
Posts: 3
Hi Hardy,

With the entitymanager's persist method, it works perfectly. It's only when i use the merge method.
I would like to have the same controls during persist or merge.
I have a alternative => execute the controls BEFORE the persist and merge call. (so, @PrePersist and @PreUpdate are no longer needed ...).

I think it's an hibernate's bug but i am not sure ...
Could you tell me how I can ask my question to someone from hibernate ?

Philippe.


Top
 Profile  
 
 Post subject:
PostPosted: Thu May 08, 2008 5:21 am 
Hibernate Team
Hibernate Team

Joined: Thu Apr 05, 2007 5:52 am
Posts: 1689
Location: Sweden
Hi Philippe,

I asked Emmanuel from the Hibernate team to have a look at this. If you don't hear anything you could always create a Jira issue to get someone to look at it.

--Hardy


Top
 Profile  
 
 Post subject:
PostPosted: Thu May 08, 2008 10:45 am 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
It might be due to the way we order merges: ie pre-persist being called on the clone version before the children merge. It is worth opening a JIRA issue with a minimal test case.
My bet is that it's going to be a tough one to fix.

I am curious, if you use Hibernate Validator, does

@NotNull @Size(min=2) Collection children;

work or does it fail as well?

_________________
Emmanuel


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 7 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.