Hi,
I'm getting an out of memory error when executing the following code:
Code:
session = HibernateUtil.getCurrentSession();
session.beginTransaction();
List<DataItem> accents = Data.ACCENT.getAll();
accents = Data.ACCENT.getAll();
The code for the Data and DataItem class is:
Code:
public enum Data implements DataChangeListener {
ACCENT("Accenten", false), //
ATTENTION_POINT("Aandachtspunten", false), //
MATERIAL("Materialen", false), //
VARIANT("Varianten", true);
private String title;
private boolean allowsSubdata;
private UniqueList<DataItem> items = new UniqueList<DataItem>();
private final transient Vector<DataChangeListener> listeners = new Vector<DataChangeListener>();
private final transient Map<Long, DataItem> idMap = new HashMap<Long, DataItem>();
Data(String title, boolean allowsSubdata) {
this.title = title;
this.allowsSubdata = allowsSubdata;
}
public List<DataItem> getAll() {
Session session = HibernateUtil.getCurrentSession();
List<DataItem> result = session.createQuery("from DataItem where rootData = ?")
.setParameter(0, this)
.list();
return result;
}
}
Code:
public class DataItem implements Comparable<DataItem>, Serializable, DataChangeListener, Lifecycle {
private static final long serialVersionUID = 1L;
private Long id;
private Data rootData;
private DataItem parent;
private String data;
private final UniqueList<DataItem> subData = new UniqueList<DataItem>();
private int level;
private boolean deprecated = false;
private transient ListenerHandler<DataChangeListener> listenerHandler = new ListenerHandler<DataChangeListener>();
private transient boolean settingData = false;
protected DataItem() {
super(); // Used by Hibernate
}
DataItem(Data rootData, String data, boolean standard) {
if (data == null) {
throw new IllegalArgumentException("The data can not be null");
}
this.rootData = rootData;
this.data = data;
parent = null;
level = 0;
initTransients();
}
DataItem(Data rootData, String data) {
this(rootData, data, false);
}
DataItem(DataItem parent, String data) {
this(parent.getRootData(), data);
this.parent = parent;
level = parent.getLevel() + 1;
}
public Long getId() {
return id;
}
protected void setIndex(int index) {
// Not used. Necessary for Hibernate.
}
public int getIndex() {
return getParent() == null ? getRootData().indexOf(this) : getParent().getAllSubData().indexOf(this);
}
public void save(Session session) {
session.saveOrUpdate(this);
for (DataItem subDataItem : getAllSubData()) {
subDataItem.save(session);
}
}
protected void setId(Long id) {
this.id = id;
}
public Data getRootData() {
return rootData;
}
protected void setRootData(Data rootData) {
this.rootData = rootData;
}
public void setDeprecated(boolean deprecated) {
settingData = true;
this.deprecated = deprecated;
for (DataItem item : getAllSubData()) {
item.setDeprecated(deprecated);
}
settingData = false;
fireEvent(new DataChangeEvent(this));
}
public boolean isDeprecated() {
return deprecated;
}
public DataItem getParent() {
return parent;
}
protected void setParent(DataItem parent) {
this.parent = parent;
}
public int getLevel() {
return level;
}
protected void setLevel(int level) {
this.level = level;
}
public String getData() {
return data;
}
public void setData(String string) {
this.data = string;
// FIXME fireEvent(new DataChangeEvent(this));
}
@Override
public String toString() {
return data;
}
public List<DataItem> getAllSubData() {
return subData;
}
protected void setAllSubData(List<DataItem> subData) {
this.subData.addAll(subData);
}
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;
}
public DataItem getSubData(Long itemId) {
DataItem item = null;
int index = 0;
while (index < subData.size() && item == null) {
DataItem subItem = subData.get(index);
if (subItem.getId().equals(itemId)) {
item = subItem;
}
index++;
}
return item;
}
public DataItem removeSubData(String string) {
DataItem removedItem = null;
int index = 0;
while (index < subData.size() && removedItem == null) {
if (subData.get(index).toString().equals(string)) {
removedItem = subData.remove(index);
}
index++;
}
if (removedItem != null) {
fireEvent(new DataChangeEvent(this, removedItem, DataChangeEvent.ITEM_REMOVED));
removedItem.removeDataChangeListener(this);
}
return removedItem;
}
public DataItem addSubData(String string) {
DataItem item = getSubData(string);
if (item == null) {
item = new DataItem(this, string);
subData.add(item);
item.addDataChangeListener(this);
fireEvent(new DataChangeEvent(this, item, DataChangeEvent.ITEM_ADDED));
}
return item;
}
public boolean hasSubData(String string) {
return getSubData(string) != null;
}
public void clearSubData() {
for (DataItem item : subData) {
item.removeDataChangeListener(this);
}
subData.clear();
fireEvent(new DataChangeEvent(this, this, DataChangeEvent.COLLECTION_CHANGE));
}
public synchronized void addDataChangeListener(DataChangeListener listener) {
listenerHandler.addListener(listener);
}
public synchronized void removeDataChangeListener(DataChangeListener listener) {
listenerHandler.removeListener(listener);
}
public int compareTo(DataItem item) {
if (item.getRootData() != getRootData()) {
throw new IllegalArgumentException("Can not compare data items from different data sets.");
}
return toString().compareTo(item.toString());
}
private void fireEvent(DataChangeEvent event) {
if (listenerHandler != null) {
listenerHandler.startNotification();
for (DataChangeListener listener : listenerHandler.getListeners()) {
listener.dataChanged(event);
}
listenerHandler.stopNotification();
}
}
public void dataChanged(DataChangeEvent event) {
if (!settingData) {
if (!subData.isEmpty()) {
deprecated = true;
for (DataItem item : subData) {
deprecated &= item.isDeprecated();
}
}
fireEvent(new DataChangeEvent(this, event.getDataItem(), event));
}
}
public boolean integrityOk() {
return id != null && rootData != null && data != null && (level == 0 || parent != null);
}
@Override
public int hashCode() {
return super.hashCode() + 37 * data.hashCode() + 37 * 37 * rootData.hashCode();
}
private void readObject(ObjectInputStream in) throws IOException,
ClassNotFoundException {
in.defaultReadObject();
initTransients();
// TEMP
if (!subData.isEmpty()) {
deprecated = true;
for (DataItem item : subData) {
deprecated &= item.isDeprecated();
}
}
}
protected void initTransients() {
settingData = false;
listenerHandler = new ListenerHandler<DataChangeListener>();
if (getParent() != null) {
addDataChangeListener(getParent());
} else {
addDataChangeListener(getRootData());
}
}
@Override
public boolean onDelete(Session session) throws CallbackException {
return NO_VETO;
}
@Override
public void onLoad(Session session, Serializable serializable) {
initTransients();
}
@Override
public boolean onSave(Session session) throws CallbackException {
return NO_VETO;
}
@Override
public boolean onUpdate(Session session) throws CallbackException {
return NO_VETO;
}
}
The mapping file for DataItem looks like this:
Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="be.bloso.vetrasoft.model.application">
<class name="DataItem" table="DATAITEM">
<id name="id" column="DATAITEM_ID">
<generator class="hilo" />
</id>
<property name="rootData" />
<property name="data" />
<property name="level" />
<property name="deprecated" />
<property name="index" update="false" />
<many-to-one name="parent" class="DataItem" />
<list name="allSubData" inverse="true" lazy="true" table="DATAITEM">
<key column="parent" />
<list-index column="INDEX" />
<one-to-many class="DataItem" />
</list>
</class>
</hibernate-mapping>
I ran test code for the DataItem class that worked but apparently retrieving all DataItems twice in the same session puts Hibernate in an infinite loop somehow. Does anyone have an idea what might be the cause of this?
Thanks in advance,
Stef Kuypers