Hibernate version:
Hibernate 3.3.1.GA
Hibernate Annotations 3.4.0.GA
Name and version of the database you are using:
Oracle 10.2g
Working with composite primary keys i encountered 2 Problems. I created a testcase to demonstrate the problems. For source code of the classes and SQL to create the tables see below.
1. CascadeType.REMOVE in Composite Primary Keys does not work
I included two examples. In example a) both classes have a primary key over one column. So the following code removes both instances from the database - as expected.
a)
import hibtest.success.HibParent;
HibParent p = (HibParent) session.get(HibParent.class, Long.valueOf(1));
session.delete(p);
If i extend the primary key of HibParent over the second column and create a PK-class (in subpackage failure.*), the following code only deletes the HibPrent-instance:
b)
import hibtest.failure.HibParent;
import hibtest.failure.HibParentPK;
HibChild c = (HibChild) session.get(HibChild.class, Long.valueOf(1));
HibParent p = (HibParent) session.get(HibParent.class, new HibParentPK(Long.valueOf(1), c));
session.delete(p);
I don't know if this is a bug or if i'm missing something.
2. Bidirectional association in Composite Keys
Uncomment get/setParent in class HibChild and execute the following:
HibChild c = (HibChild) session.get(HibChild.class, Long.valueOf(1));
On my system Hibernate loads Child-Instances until a stackoverflow occurs:
2008-12-17 17:34:18,235 DEBUG SQL:111 - /* load hibtest.HibChild */ select hibchild0_.id ...
...
2008-12-17 17:34:18,235 DEBUG SQL:111 - /* load hibtest.HibChild */ select hibchild0_.id ...
2008-12-17 17:34:18,242 DEBUG SQL:111 - /* load hibtest.HibChild */ select hibchild0_.id ...
...
Caused by: java.lang.StackOverflowError
Am I doing something wrong or are these bugs? If someone confirms that these are bugs I would file a bug report.
hibtest.HibChild
package hibtest;
import hibtest.failure.HibParent;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.OneToOne;
@Entity
public class HibChild {
private Long id;
private String payload;
private HibParent parent;
@Id
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getPayload() {
return payload;
}
public void setPayload(String payload) {
this.payload = payload;
}
// @OneToOne(mappedBy="pk.child")
// public HibParent getParent() {
// return parent;
// }
//
// public void setParent(HibParent parent) {
// this.parent = parent;
// }
}
hibtest.success.HibParent
package hibtest.success;
import hibtest.HibChild;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
@Entity
public class HibParent {
private Long id;
private HibChild child;
@Id
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@OneToOne(fetch=FetchType.EAGER, cascade=CascadeType.ALL)
@JoinColumn(name="fk")
public HibChild getChild() {
return child;
}
public void setChild(HibChild child) {
this.child = child;
}
}
hibtest.failure.HibParent
package hibtest.failure;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
@Entity
public class HibParent {
private HibParentPK pk;
@EmbeddedId
public HibParentPK getPk() {
return pk;
}
public void setPk(HibParentPK pk) {
this.pk = pk;
}
}
hibtest.failure.HibParentPK
package hibtest.failure;
import hibtest.HibChild;
import java.io.Serializable;
import javax.persistence.CascadeType;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
public class HibParentPK implements Serializable {
private static final long serialVersionUID = -2558079539086583257L;
private Long id;
private HibChild child;
public HibParentPK() {
super();
}
public HibParentPK(Long id, HibChild child) {
this();
this.id = id;
this.child = child;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@OneToOne(fetch=FetchType.EAGER, cascade=CascadeType.ALL)
@JoinColumn(name="fk")
public HibChild getChild() {
return child;
}
public void setChild(HibChild child) {
this.child = child;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((child == null) ? 0 : child.hashCode());
result = prime * result + ((id == null) ? 0 : id.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
HibParentPK other = (HibParentPK) obj;
if (child == null) {
if (other.child != null) {
return false;
}
} else if (!child.equals(other.child)) {
return false;
}
if (id == null) {
if (other.id != null) {
return false;
}
} else if (!id.equals(other.id)) {
return false;
}
return true;
}
}
SQL
CREATE TABLE HIB_CHILD
(
ID NUMBER NOT NULL,
PAYLOAD VARCHAR(20),
CONSTRAINT HIB_CHILD_PK PRIMARY KEY(ID) ENABLE
);
CREATE TABLE HIB_PARENT
(
ID NUMBER NOT NULL,
FK NUMBER REFERENCES HIB_CHILD(ID),
CONSTRAINT HIB_PARENT_PK PRIMARY KEY(ID, FK) ENABLE
);
INSERT INTO HIB_CHILD (ID, PAYLOAD) VALUES ('1', 'xxxxxxxx');
INSERT INTO HIB_PARENT (ID, FK) VALUES ('1', '1');
|