Hello,
I am trying a very simple example of persisting an Object graph on a Oracle 10g DB.
I am using hibernate 3.2.5.GA and annotations.
I fail on integrity constraints , I could see that the entity parameters (where the FK is) are bounded to 0.
The example:
I have 4 entities (Parent, child, grandchild and sibling)
where two of them (parent and child) are using a Oracle sequence.
(I suspect this is the problem)
The sibling and grandchild have many-to-one relationship and they are both keeping a composite id.
As I am optimistic by nature, I created new objects for all of the entities, associated it using setters and then just called save() expecting
the whole tree to be persisted.
I understood that hibernate will know to order the SQL statements such that I won't violate integrity constraints. It seems that something goes wrong.
I also tried several different approaches such as calling save() on all/one/parent/child entities and from different locations, flushing the session in the middle/start/end of the process, etc. None of these seems to work .
I'll just pour the whole stuff in here, not because I am lazy but because I think it is self explanatory, also I will spare you some of my poor English.
Main Class:
Code:
package com.example;
public class ExampleTester {
@Transactional
public static void main(String argv[]){
ExampleDaoSupport exampleDaoSupport = new ExampleDaoSupport();
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("storepi-spring/applicationContext-hibernate.xml");
SessionFactory sessionFactory = (SessionFactory) applicationContext.getBean("sessionFactory");
exampleDaoSupport.setSessionFactory(sessionFactory);
Parent parent = new Parent();
Child child = new Child();
Sibling sibling = new Sibling();
GrandChild grandChild = new GrandChild();
SiblingId siblingId = new SiblingId();
GrandChildId grandChildId = new GrandChildId();
//Parent - child
child.setParent(parent);
Collection<Child> childs = new ArrayList<Child>();
childs.add(child);
parent.setChilds(childs);
//Parent - Sibling
siblingId.setOtherik(1);
siblingId.setParentik(parent.getIk());
sibling.setId(siblingId);
sibling.setParent(parent);
Collection<Sibling> siblings = new ArrayList<Sibling>();
siblings.add(sibling);
parent.setSiblings(siblings);
//Child - Grandchild
grandChild.setId(grandChildId);
grandChild.setChild(child);
Collection<GrandChild> grandchildren = new ArrayList<GrandChild>();
grandchildren.add(grandChild);
child.setGrandchildren(grandchildren);
//GrandChild Sibling - 55123
grandChild.setSibling(sibling);
Set<GrandChild> grandchildren1 = new HashSet<GrandChild>();
grandchildren1.add(grandChild);
sibling.setGrandchildren(grandchildren1);
exampleDaoSupport.create(child);
exampleDaoSupport.create(sibling);
exampleDaoSupport.create(grandChild);
exampleDaoSupport.create(parent);
}
}
Parent class Code:
package com.example;
import java.util.Collection;
import java.util.Date;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
@Entity
@Table(name = "TMP_PARENT"/*, schema = "SPI_V10"*/, uniqueConstraints = {})
public class Parent {
private int ik;
private Date creationdate;
private Collection<Child> childs;
private Collection<Sibling> siblings;
/**
* @return the childs
*/
@OneToMany(cascade = { CascadeType.ALL }, fetch = FetchType.LAZY, mappedBy = "parent")
public Collection<Child> getChilds() {
return childs;
}
/**
* @param childs the childs to set
*/
public void setChilds(Collection<Child> childs) {
this.childs = childs;
}
/**
* @return the creationdate
*/
@Column(name = "CREATIONDATE", unique = false, nullable = true, insertable = true, updatable = true, length = 11)
public Date getCreationdate() {
return creationdate;
}
/**
* @param creationdate the creationdate to set
*/
public void setCreationdate(Date creationdate) {
this.creationdate = creationdate;
}
/**
* @return the ik
*/
@Id
@Column(name = "IK", unique = true, nullable = false, insertable = true, updatable = true, precision = 5, scale = 0)
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator = "parent_seq")
@SequenceGenerator(name="parent_seq", sequenceName = "PARENT_SEQ")
public int getIk() {
return ik;
}
/**
* @param ik the ik to set
*/
public void setIk(int ik) {
this.ik = ik;
}
/**
* @return the siblings
*/
@OneToMany(cascade = { CascadeType.ALL }, fetch = FetchType.LAZY, mappedBy = "parent")
public Collection<Sibling> getSiblings() {
return siblings;
}
/**
* @param siblings the siblings to set
*/
public void setSiblings(Collection<Sibling> siblings) {
this.siblings = siblings;
}
}
Child
Code:
package com.example;
@Entity
@Table(name = "TMP_CHILD"/*, schema = "SPI_V10"*/, uniqueConstraints = {})
public class Child {
private int ik;
private Date creationdate;
private Parent parent;
private Collection<GrandChild> grandchildren;
/**
* @return the creationdate
*/
public Date getCreationdate() {
return creationdate;
}
/**
* @param creationdate the creationdate to set
*/
public void setCreationdate(Date creationdate) {
this.creationdate = creationdate;
}
/**
* @return the ik
*/
@Id
@Column(name = "IK", unique = true, nullable = false, insertable = true, updatable = true, precision = 5, scale = 0)
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator = "child_seq")
@SequenceGenerator(name="child_seq", sequenceName = "CHILD_SEQ")
public int getIk() {
return ik;
}
/**
* @param ik the ik to set
*/
public void setIk(int ik) {
this.ik = ik;
}
/**
* @return the parent
*/
@ManyToOne(cascade = {}, fetch = FetchType.LAZY)
@JoinColumn(name = "PARENT_IK", unique = false, nullable = false, insertable = true, updatable = true)
public Parent getParent() {
return parent;
}
/**
* @param parent the parent to set
*/
@Column(name = "CREATIONDATE", unique = false, nullable = false, insertable = true, updatable = true, length = 11)
public void setParent(Parent parent) {
this.parent = parent;
}
/**
* @return the grandchildren
*/
@OneToMany(cascade = { CascadeType.ALL }, fetch = FetchType.LAZY, mappedBy = "child")
public Collection<GrandChild> getGrandchildren() {
return grandchildren;
}
/**
* @param grandchildren the grandchildren to set
*/
public void setGrandchildren(Collection<GrandChild> grandchildren) {
this.grandchildren = grandchildren;
}
}
GrandChild
Code:
package com.example;
import java.util.Date;
import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides;
import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.JoinColumns;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
@Entity
@Table(name = "TMP_GRANDCHILD"/*, schema = "SPI_V10"*/, uniqueConstraints = {})
public class GrandChild {
private GrandChildId id;
private Date creationdate;
private Child child;
private Sibling sibling;
/**
* @return the id
*/
@EmbeddedId
@AttributeOverrides( {
@AttributeOverride(name = "childik", column = @Column(name = "CHILD_IK", unique = false, nullable = false, insertable = true, updatable = true, precision = 5, scale = 0)),
@AttributeOverride(name = "parentik", column = @Column(name = "PARENT_IK", unique = false, nullable = false, insertable = true, updatable = true, precision = 5, scale = 0)),
@AttributeOverride(name = "otherik", column = @Column(name = "OTHER_IK", unique = false, nullable = false, insertable = true, updatable = true, precision = 5, scale = 0)) })
public GrandChildId getId() {
return id;
}
@ManyToOne(cascade = {}, fetch = FetchType.LAZY)
@JoinColumn(name = "CHILD_IK", referencedColumnName ="IK", unique = false, nullable = false, insertable = false, updatable = false)
public Child getChild() {
return child;
}
/**
* @param child
* the child to set
*/
public void setChild(Child child) {
this.child = child;
}
/**
* @return the creationdate
*/
@Column(name = "CREATIONDATE", unique = false, nullable = true, insertable = true, updatable = true, length = 11)
public Date getCreationdate() {
return creationdate;
}
/**
* @param creationdate
* the creationdate to set
*/
public void setCreationdate(Date creationdate) {
this.creationdate = creationdate;
}
/**
* @param id
* the id to set
*/
public void setId(GrandChildId id) {
this.id = id;
}
/**
* @return the sibling
*/
@ManyToOne(cascade = {}, fetch = FetchType.LAZY)
@JoinColumns( {
@JoinColumn(name = "PARENT_IK", referencedColumnName ="PARENT_IK", unique = false, nullable = false, insertable = false, updatable = false),
@JoinColumn(name = "OTHER_IK",referencedColumnName ="OTHER_IK", unique = false, nullable = false, insertable = false, updatable = false) })
public Sibling getSibling() {
return sibling;
}
/**
* @param sibling
* the sibling to set
*/
public void setSibling(Sibling sibling) {
this.sibling = sibling;
}
}
SiblingCode:
package com.example;
import java.util.Date;
import java.util.Set;
import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
@Entity
@Table(name = "TMP_SIBLING"/*, schema = "SPI_V10"*/, uniqueConstraints = {})
public class Sibling {
private SiblingId id;
private Date creationdate;
private Set<GrandChild> grandchildren;
private Parent parent;
/**
* @return the id
*/
@EmbeddedId
@AttributeOverrides( {
@AttributeOverride(name = "otherik", column = @Column(name = "OTHER_IK", unique = false, nullable = false, insertable = true, updatable = true, precision = 5, scale = 0)),
@AttributeOverride(name = "parentik", column = @Column(name = "PARENT_IK", unique = false, nullable = false, insertable = true, updatable = true, precision = 5, scale = 0))
})
public SiblingId getId() {
return id;
}
/**
* @return the creationdate
*/
@Column(name = "CREATIONDATE", unique = false, nullable = true, insertable = true, updatable = true, length = 11)
public Date getCreationdate() {
return creationdate;
}
/**
* @param creationdate the creationdate to set
*/
public void setCreationdate(Date creationdate) {
this.creationdate = creationdate;
}
/**
* @return the grandchildren
*/
@OneToMany(cascade = { CascadeType.ALL }, fetch = FetchType.LAZY, mappedBy = "sibling")
public Set<GrandChild> getGrandchildren() {
return grandchildren;
}
/**
* @param grandchildren the grandchildren to set
*/
public void setGrandchildren(Set<GrandChild> grandchildren) {
this.grandchildren = grandchildren;
}
/**
* @param id the id to set
*/
public void setId(SiblingId id) {
this.id = id;
}
/**
* @return the parent
*/
@ManyToOne(cascade = {}, fetch = FetchType.LAZY )
@JoinColumn(name = "PARENT_IK", unique = false, nullable = false, insertable = false, updatable = false)
public Parent getParent() {
return parent;
}
/**
* @param parent the parent to set
*/
public void setParent(Parent parent) {
this.parent = parent;
}
}
Thanks