I want to save/persist an entity(parent) with unique children objects included only by the parent object. Anything works well until a duplicate child appears, here I get following Exception:
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry
At first you have to know that I'm using the expression session.bySimpleNaturalId(Child.class).load(child.getMd5Hash())
to check if the child already exists, because all children objects have unique hash values(created after initializing) which are explicitly not assigned as the primary key(their primary key is an auto-increment; strategy = GenerationType.TABLE
).
Whether I use session.merge(child)
or any other expression on my DAO, I get the same exception.
My Parent-Object:
@Entity
@Table(name = "parent")
public class Parent implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.TABLE)
private Long id = null;
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name = "kind_child_id", referencedColumnName = "md5hash")
private Child firstChild;
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name = "rude_child_id", referencedColumnName = "md5hash")
private Child secondChild;
//private String attributes;
//Getters & Setters
My Child-Object:
@Entity
@Table(name = "child")
public class Child implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.TABLE)
private Long id = null;
@NaturalId
@Column(name="md5hash", unique=true)
private char[] md5hash = new char[32];
//private String attributes;
//Getters & Setters
And here is my method to save/persist a parent(validations included):
public void writeParent(Parent parent) {
try {
if (parent != null) {
if (globalSession == null) {
globalSession = getSessionFactory().openSession();
}
globalSession.beginTransaction();
if (parent.getFirstChild() != null) {
Child tempFirstChild = (Child) globalSession.bySimpleNaturalId(Child.class).load(parent.getFirstChild().getMd5Hash());
if (tempFirstChild != null) {
parent.setFirstChild(tempFirstChild);
//globalSession.merge(tempFirstChild);
//throws MySQLICV-Exception
//globalSession.update(tempFirstChild);
//throws MySQLICV-Exception
}
}
if (parent.getSecondChild() != null) {
Child tempSecondChild = (Child) globalSession.bySimpleNaturalId(Child.class).load(parent.getSecondChild().getMd5Hash());
if (tempSecondChild != null) {
parent.setSecondChild(tempSecondChild);
//globalSession.merge(tempSecondChild);
//throws MySQLICV-Exception
//globalSession.update(tempSecondChild);
//throws MySQLICV-Exception
}
}
globalSession.saveOrUpdate(parent);
//globalSession.persist(parent);
globalSession.getTransaction().commit();
}
} catch (Exception ex) {
log.error("FAILURE: ", ex);
}
finally{
globalSession.close();
}
}
Maybe I didn't understand the entire documentary that's why I came up for this: Do I even have to tell Hibernate to merge the found entities?
How can I tell Hibernate that those children shouldn't be treated as new objects which need to be persisted?
Or do I even have to switch to bidirectional relations?(I'm currently not allowed to use bidirectional relations in this case)
Any hints are welcome and very appreciated, thank you in advance. Regards, Yeti