I'm having trouble with a collection mapping that I hope the Hibernate community can help me out with.
I have a Person class that has a reflexive relationship. Below are some requirements of the mapping.
A Person has one and only one parent(Person).
A Person has many children(Person).
A Person can be a child of many Persons.
All in all I believe I have a unidirectional many-to-one from Person to parent and a unidirectional from Person to children. I believe this is right but not positive (not positive because I'm having issues). The tricky part to this relationship is that a child knows of only one parent but does not know the Persons that it’s a child for. Let’s look at the code.
I have two tables:
person: for the Person class with a parent_id column which is the foreign key to itself.
Code:
CREATE TABLE person (
id CHAR(32) NOT NULL,
parent_id char(32),
name VARCHAR(255) NOT NULL,
descr VARCHAR(255),
PRIMARY KEY pk_person (id)
)
ALTER TABLE person ADD CONSTRAINT fk_parent_person
FOREIGN KEY (parent_id) REFERENCES person (id);
person_link: a link table for my relationship (many-to-many collection) that has a 'branch_id', 'leaf_id', and 'sequence' column. 'branch_id' represents the parent, 'leaf_id' represents the child and 'sequence' for the order of the list collection they are mapped to.
Code:
CREATE TABLE person_link (
branch_id CHAR(32) NOT NULL,
leaf_id CHAR(32) NOT NULL,
sequence INT,
PRIMARY KEY pk_person_link (branch_id, leaf_id)
)
ALTER TABLE person_link ADD CONSTRAINT fk_branch_person
FOREIGN KEY (branch_id) REFERENCES person (id);
ALTER TABLE person ADD CONSTRAINT fk_leaf_person
FOREIGN KEY (leaf_id) REFERENCES person (id);
Here's a snipit of my Parent class.
Code:
public class Parent {
...
private Person parent;
private List<Person> children;
...
}
Snipit of the mapping.
Code:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
...
<many-to-one name="parent" class="com.xyz.Parent"
column="parent_id" />
<list name="children" table="person_link" cascade="save-update"
lazy="true">
<key column="branch_id" />
<list-index column="sequence" />
<many-to-many class="com.xyz.Parent" column="leaf_id" />
</list>
...
I can add and delete to the collection just fine. It's when I want to change the order of the collection is when I have issues.
The code I use to change the order follows:
Code:
Collections.swap(person.getChildren(), index, index-1);
personDao.store(person);
I get the following exception:
Code:
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.dao.DataIntegrityViolationException: Hibernate operation: Could not execute JDBC batch update; SQL [update person_link set leaf_id=? where branch_id=? and sequence=?]; Duplicate entry '40288fe509a271ff0109a272038a0002-40288fe509a7d78f0109a7d88c47000' for key 1; nested exception is java.sql.BatchUpdateException: Duplicate entry '40288fe509a271ff0109a272038a0002-40288fe509a7d78f0109a7d88c47000' for key 1
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:406)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:348)
javax.servlet.http.HttpServlet.service(HttpServlet.java:689)
javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
My only thought after writing this up was that there may be something I don't understand in regards to lazy loading. Might have to eager fetch this to actually change the order.
Any thoughts?
Thanks in advance.
Hibernate version:3.1.2
Name and version of the database you are using:MySQL: 5.0.18
MySQL JDBC: 3.1.12[/code]