PROBLEM STATEMENT
I am trying to create a parent-child child relationship using hibernate 3.3.1 on MySql 5.0. Parent table has 2 fields ID and Name, ID is integer and the primary key, Name is a VARCHAR (30). Child table has 3 fields, ID, Name, and Parent_Id. ID is integer and the primary key, Name is VARCHAR(30), and Parent_Id is an integer and a foreign key which references Parent's ID
What I want is, the Parent_ID value in the Child class should be populated automatically along with the ID in the PARENT table because it is the foreign key to the ID in Parent's table. But it is not happening and a null value for the foreign key goes to the MySQL and the database complains. (The foreign key cannot be null in this application) Is there a way we can link the foreign key in the child table so that it is automatically populated with the value of the key it is linked to?
Mapping documents
Parent.hbm.xml
Code:
<hibernate-mapping>
<class name="entities.Parent" table="parent" >
<id name="id" column="id" type="int">
<generator class="increment"/>
</id>
<property name="name" />
<set name="children" inverse="true" cascade="all">
<key column="parent_id"/>
<one-to-many class="entities.Child"/>
</set>
</class>
</hibernate-mapping>
Child.hbm.xmlCode:
<hibernate-mapping>
<class name="entities.Child" table="child">
<id name="id" column="id" type="int" >
<generator class="increment"/>
</id>
<property name="name" />
<property name="parent_id"/>
</class>
</hibernate-mapping>
hibernate.cfg.xmlCode:
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernatetutorial</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">root</property>
<property name="hibernate.connection.pool_size">10</property>
<property name="show_sql">true</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<!-- Mapping files -->
<mapping resource="parent.hbm.xml"/>
<mapping resource="child.hbm.xml"/>
</session-factory>
</hibernate-configuration>
[/b]
Code of the Child ObjectCode:
package entities;
public class Child {
private String name = null;
private int id = -1;
private int parent_id= -1;
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 int getParent_id() {
return parent_id;
}
public void setParent_id(int parent_id) {
this.parent_id = parent_id;
}
}
Code of the Parent ObjectCode:
package entities;
import java.util.Set;
public class Parent {
private String name = null;
private int id;
private Set children = null;
public Set getChildren() {
return children;
}
public void setChildren(Set children) {
this.children = children;
}
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;
}
}
Code of the test classCode:
package test;
import java.util.HashSet;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import entities.Child;
import entities.Parent;
public class TestParentChild {
public static void main(String[] args) {
try {
SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
Session session =sessionFactory.openSession();
session.getTransaction().begin();
Parent p= new Parent();
p.setName("mom");
Child c = new Child();
c.setName("kid1");
p.setChildren(new HashSet());
p.getChildren().add(c);
session.save(p);
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Full stack trace of exception that occurs
Apr 23, 2008 4:13:28 PM org.hibernate.util.JDBCExceptionReporter logExceptions
WARNING: SQL Error: 1452, SQLState: 23000
Apr 23, 2008 4:13:28 PM org.hibernate.util.JDBCExceptionReporter logExceptions
SEVERE: Cannot add or update a child row: a foreign key constraint fails (`hibernatetutorial/child`, CONSTRAINT `FK5A3F51C19D5F867` FOREIGN KEY (`PARENT_ID`) REFERENCES `parent` (`ID`))
Apr 23, 2008 4:13:28 PM org.hibernate.event.def.AbstractFlushingEventListener performExecutions
SEVERE: Could not synchronize database state with session
org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:253)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:235)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:139)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
at test.TestParentChild.main(TestParentChild.java:28)
Caused by: java.sql.BatchUpdateException: Cannot add or update a child row: a foreign key constraint fails (`hibernatetutorial/child`, CONSTRAINT `FK5A3F51C19D5F867` FOREIGN KEY (`PARENT_ID`) REFERENCES `parent` (`ID`))
at com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:1237)
at com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:936)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:246)
... 8 more
org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:253)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:235)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:139)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
at test.TestParentChild.main(TestParentChild.java:28)
Caused by: java.sql.BatchUpdateException: Cannot add or update a child row: a foreign key constraint fails (`hibernatetutorial/child`, CONSTRAINT `FK5A3F51C19D5F867` FOREIGN KEY (`PARENT_ID`) REFERENCES `parent` (`ID`))
at com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:1237)
at com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:936)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:246)
... 8 more
Any thoughts from experts out there? Thanks!