-->
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.  [ 6 posts ] 
Author Message
 Post subject: Add a new child without fetching all child data(one to Many)
PostPosted: Thu Feb 28, 2008 3:13 pm 
Newbie

Joined: Wed Feb 27, 2008 4:22 pm
Posts: 4
3.2.5.ga
Hibernate Annotations : 3.3.0


I have a problem trying to add a new row in a one to many relationship.

I created a simple program to test this
A parent has multiple child. I retrieve only the parent using a HQL query.
Later I want to add a new child without retrieving all the other child in the list. Is there any way I can add a new child without retrieveing all the other child associated with the parent. The issue I am having is I cannot create a new child and call a separate insert on this child.. Is failing on Backref


DAO methods

Code:
public Parent getParent(Long p) {
      String queryString =
         "from Parent p where " +
         " p.parentId = :parentId" ;   
      Parent p1 = (Parent) getSessionFactory().getCurrentSession()
      .createQuery(queryString).setParameter("parentId", p).uniqueResult();
      return p1;      
   }


   public void saveChild(Child c) {      
      getSessionFactory().getCurrentSession()
      .save(c);
   }




Parent Class
Code:
@Entity
@Table(name = "P_PARENT" )
public class Parent {
   private Long      parentId;
   private Set<Child>         child =new HashSet<Child>();
   
   @Id
   @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="scenario_seq")
   @SequenceGenerator(name="scenario_seq", sequenceName = "TEST_SCENARIO_SEQ")
   @Column(name="PARENT_ID")
   public Long getParentId() {
      return parentId;
   }

   public void setParentId(Long parentId) {
      this.parentId = parentId;
   }
   
    @OneToMany(cascade=CascadeType.ALL)
    @org.hibernate.annotations.Cascade(value=org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
    @JoinColumn(name="PARENT_ID", nullable=false)
   public Set<Child> getChild() {
      return child;
   }

   public void setChild(Set<Child> child) {
      this.child = child;
   }





Child Class
Code:

@Entity
@Table(name = "P_CHILD" )
public class Child {
   private Long      parentId;
   private Long      childId;
   private String       description;
   
   @Column(name="PARENT_ID", insertable=false, updatable=false, nullable=false)
   public Long getParentId() {
      return parentId;
   }

   public void setParentId(Long parentId) {
      this.parentId = parentId;
   }

   @Id
   @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="scenario_seq")
   @SequenceGenerator(name="scenario_seq", sequenceName = "TEST_SCENARIO_SEQ")
   @Column(name="CHILD_ID")
   public Long getChildId() {
      return childId;
   }

   public void setChildId(Long childId) {
      this.childId = childId;
   }




Client
Code:
p1 = dao.getParent(13600l);
//This is what I want .. Create a new independent child and save it
Child c = new Child();
c.setParentId(1360l);
dao.saveChild(c);

But this fails with
Code:
Exception in thread "main" org.hibernate.PropertyValueException: not-null property references a null or transient value: com.fedex.ore.intl.domain.Child._childBackref
   at org.hibernate.engine.Nullability.checkNullability(Nullability.java:72)
   at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:290)


If I put this code it works
Code:
p1.getChild().add(c);

But it retrieves all the child associated to this parent which is a huge overhead.


Please let me know if there is a way to resolve this..

Thanks


Top
 Profile  
 
 Post subject: Re: Add a new child without fetching all child data(one to M
PostPosted: Thu Feb 28, 2008 3:35 pm 
Expert
Expert

Joined: Wed Apr 11, 2007 11:39 am
Posts: 735
Location: Montreal, QC
where is _childBackref defined?



Farzad-


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 28, 2008 3:52 pm 
Newbie

Joined: Wed Feb 27, 2008 4:22 pm
Posts: 4
I feel the getParentId() in the child creates the backRef when it is trying to save the child on its own


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 28, 2008 3:54 pm 
Newbie

Joined: Wed Feb 27, 2008 4:22 pm
Posts: 4
I feel the getParentId() in the child creates the backRef when it is trying to save the child on its own


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 28, 2008 3:59 pm 
Expert
Expert

Joined: Wed Apr 11, 2007 11:39 am
Posts: 735
Location: Montreal, QC
pravnrao wrote:
I feel the getParentId() in the child creates the backRef when it is trying to save the child on its own


ParentId is a long. Hibernate will not have a slightest clue it is the id of the parent class. Look in your source code and find what that backRef is. Meanwhile the mapping is weird. You are explicitly telling hibernate not set the parent id:


Code:
   @Column(name="PARENT_ID", insertable=false, updatable=false, nullable=false)
   public Long getParentId() {
      return parentId;
   }


why is that?


Farzad-


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 28, 2008 4:54 pm 
Newbie

Joined: Thu Jan 04, 2007 1:36 pm
Posts: 16
Hi,
I havent done much via annotations...but I guess the definitions are pretty clear as to what you're trying to do or how you've defined the mapping.
The way you've set it up is such that a Child can be created ONLY via the Parent (ie. Parent -> Child). You do not have a bi-directional mapping set for Child -> Parent.

You'd probably have to either remove the insertable=false, updatable=false setting in your Child class, coz you're trying to add the parent id to the Child in your code and trying to save it..but your definition says its not and insert/update column except via Child class. So you should either have another property added to your Child class which points back to your Parent or remove the above mentioned attributes to make Child class persistable on its own.

You could then try...
Parent p = session.load(Parent.class, <id>);
Child c = new Child();
c.setParent(p);
session.save(c);

Regards,
Arun


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 6 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.