Hi there,
I created a class (code attached below) that has child elements of the same type. I used CascadeType. All but when I save a newly created object, the child objects are not saved. I did a bit of debugging and discovered some really weird behavior.
I'll list the code here first (I left out all the code that is irrelevant) to facilitate explaining what happens:
Code:
@Entity
@SequenceGenerator(name = "SEQ_DATAITEM", sequenceName = "dataitem_sequence")
public class DataItem implements Comparable<DataItem>, Serializable, DataChangeListener {
private static final long serialVersionUID = 1L;
private Long id;
private DataItem parent;
private final UniqueList<DataItem> subData = new UniqueList<DataItem>();
protected DataItem() {
super(); // Used by Hibernate
}
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_DATAITEM")
public Long getId() {
return id;
}
protected void setId(Long id) {
this.id = id;
}
@ManyToOne
@JoinColumn(name = "parent_fk")
public DataItem getParent() {
return parent;
}
protected void setParent(DataItem parent) {
this.parent = parent;
}
@OneToMany(cascade = CascadeType.ALL, mappedBy = "parent")
public List<DataItem> getAllSubData() {
return subData;
}
protected void setAllSubData(List<DataItem> subData) {
this.subData.clear();
this.subData.addAll(subData);
}
public DataItem addSubData(String string) {
DataItem item = getSubData(string);
if (item == null) {
item = new DataItem(this, string);
subData.add(item);
}
return item;
}
public DataItem getSubData(String string) {
DataItem item = null;
int index = 0;
while (index < subData.size() && item == null) {
DataItem subItem = subData.get(index);
if (subItem.toString().equals(string)) {
item = subItem;
}
index++;
}
return item;
}
}
The test code I execute is the following:
Code:
DataItem dataItem = Data.ACCENT.add("test"); // Just creates a new DataItem
dataItem.addSubData("subdata 1");
dataItem.addSubData("subdata 2");
session.beginTransaction();
session.save(dataItem);
session.getTransaction().commit();
reset(); // closes and reopens the db
session.beginTransaction();
List<DataItem> results = session.createQuery("from DataItem").list();
Assert.assertEquals(1, results.size());
dataItem = results.get(0);
Assert.assertSame(Data.ACCENT, dataItem.getRootData());
Assert.assertEquals("test", dataItem.getData());
Assert.assertEquals(2, dataItem.getAllSubData().size());
for (DataItem subItem : dataItem.getAllSubData()) {
Assert.assertSame(subItem.getParent(), dataItem);
Assert.assertTrue(subItem.getData().startsWith("subdata"));
}
Now, I set a breakpoint in the DataItem.setAllSubData() method and what happens is that, when I clear this.subData, the parameter that is passed is being cleared too although they are different objects. By the way, this happens during the save operation.
Is there anyone who has an idea on how to tackle this? By the way, UniqueList is a list that won't allow duplicates.
Thanks in advance,
Stef