Hi,
I am new to hibernate and can anyone please explain me why the Cascading options with one-to-many relation is not working as expected with bidirectional relationship.
For eg :
I have a Parent object which is having an one-to-many relation(with cascade option set to "all") to a child object,
I am loading an existing parent object from the database and try add a new child object
to the parent(without explicitly saving the child object) ,saving the parent alone. But the
child object is not saved in database and also the parent object is not updated.
Please explain me why this is not working in hibernate? In which scenario the cascading option 'all' will work?
Thanks in advance.
- Ram Balaji S
Parent.java
Code:
package hibernatetest;
import java.util.Set;
/**
* @hibernate.class table="PARENT"
* @hibernate.query name="fetchParent" query="from Parent m"
*
* TODO To change the template for this generated type comment go to
* Window - Preferences - Java - Code Style - Code Templates
*/
public class Parent {
private Long id;
private String name;
private String color;
private Set children;
public Parent(){
}
public Parent(String name,String color){
this.name = name;
this.color = color;
}
/**
*
* @hibernate.set inverse="true" lazy="false" batch-size="10" cascade="all"
* @hibernate.collection-key column="PARENT_ID" not-null="true"
*
* @hibernate.collection-one-to-many
* class="hibernatetest.Child"
*
*
* @return Returns the children.
*/
public Set getChildren() {
return children;
}
/**
* @param children The children to set.
*/
public void setChildren(Set children) {
this.children = children;
}
/**
* @hibernate.property column="COLOR"
* @return Returns the color.
*/
public String getColor() {
return color;
}
/**
* @param color The color to set.
*/
public void setColor(String color) {
this.color = color;
}
/**
* @hibernate.id generator-class="native" column="PARENT_ID"
*
* @return Returns the id.
*/
public Long getId() {
return id;
}
/**
* @param id The id to set.
*/
public void setId(Long id) {
this.id = id;
}
/**
* @hibernate.property column="NAME"
* @return Returns the name.
*/
public String getName() {
return name;
}
/**
* @param name The name to set.
*/
public void setName(String name) {
this.name = name;
}
/**
* This will add the Child bject to the set
* @param
*/
public void addChild(Child child)
{
child.setParent(this);
}
}
Child.java
Code:
package hibernatetest;
/**
*
* @hibernate.class table="CHILD"
* @author Ram Balaji S
*
* TODO To change the template for this generated type comment go to
* Window - Preferences - Java - Code Style - Code Templates
*/
public class Child {
private Long id;
private String name;
private String color;
private Parent parent;
/**
* @hibernate.many-to-one column="PARENT_ID"
* class="hibernatetest.Parent" not-null="true"
*
* @return Returns the parent.
*/
public Parent getParent() {
return parent;
}
/**
* @param parent The parent to set.
*/
public void setParent(Parent parent) {
this.parent = parent;
}
public Child(){
}
public Child(String name,String color){
this.name = name;
this.color = color;
}
/**
* @hibernate.property column="COLOR"
*
*/
public String getColor() {
return color;
}
/**
* @param color The color to set.
*/
public void setColor(String color) {
this.color = color;
}
/**
* @hibernate.id generator-class="native" column="CHILD_ID"
*
* @return Returns the id.
*/
public Long getId() {
return id;
}
/**
* @param id The id to set.
*/
public void setId(Long id) {
this.id = id;
}
/**
* @hibernate.property column="NAME"
* @return Returns the name.
*/
public String getName() {
return name;
}
/**
* @param name The name to set.
*/
public void setName(String name) {
this.name = name;
}
}
HibernateTest.java
Code:
/*
* Created on 13/01/2010
*
* TODO To change the template for this generated file go to
* Window - Preferences - Java - Code Style - Code Templates
*/
package hibernatetest;
import java.util.Set;
import org.apache.log4j.Logger;
import org.hibernate.FlushMode;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.classic.Session;
/**
* @author Ram Balaji S
*
* TODO To change the template for this generated type comment go to
* Window - Preferences - Java - Code Style - Code Templates
*/
public class HibernateTest {
private static Logger LOG = Logger.getLogger(HibernateTest.class);
public static void main(String[] args) {
try
{
SessionFactory sessionFactory =
new Configuration().configure().buildSessionFactory();
//creating session from the session factory
Session session = sessionFactory.openSession();
//This method will flushes the session.
session.setFlushMode( FlushMode.AUTO );
//Creating a transaction.
Transaction transaction = session.beginTransaction();
saveParentAndChild(session);
//commit the transaction
transaction.commit();
LOG.info("Transaction committed");
}
catch( Throwable e )
{
e.printStackTrace();
}
}
/**
* Saving the Parent without saving the child
* tesitng the cascading options with all.
* @param session
*/
public static void saveParentAndChild(Session session){
LOG.info("Save Parent and child");
Parent parent = new Parent();
//Loading the existing parent object from DB
session.load(parent,new Long(1));
//Getting the child objects
Set children = parent.getChildren();
//Creating a new child.
Child child = new Child("A268","Berry");
//setting the parent to child (bi directional)
child.setParent(parent);
//saving the child
//session.save(child);
//Adding a new one to the parent
parent.addChild(child);
//finally saving the parent.
session.save(parent);
}
}