-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 posts ] 
Author Message
 Post subject: Out of memory error with 2 same calls in same session
PostPosted: Thu Oct 15, 2009 9:59 am 
Newbie

Joined: Fri Aug 14, 2009 8:06 am
Posts: 19
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


Top
 Profile  
 
 Post subject: Re: Out of memory error with 2 same calls in same session
PostPosted: Thu Oct 15, 2009 10:22 am 
Newbie

Joined: Fri Aug 14, 2009 8:06 am
Posts: 19
The following also generates an out of memory error.
Code:
      session = HibernateUtil.getCurrentSession();
      session.beginTransaction();

      List<?> result = session.createQuery("from DataItem where rootData = ? and index = ?")
            .setParameter(0, Data.ACCENT)
            .setInteger(1, 0)
            .list();

      session.getTransaction().commit();
      session.beginTransaction();

      result = session.createQuery("from DataItem where rootData = ? and index = ?")
            .setParameter(0, Data.ACCENT)
            .setInteger(1, 0)
            .list();

      session.getTransaction().commit();


While executing the query only once causes no problem whatsoever. I should be able to repeat queries right?

Cheers,
Stef


Top
 Profile  
 
 Post subject: Re: Out of memory error with 2 same calls in same session
PostPosted: Fri Oct 16, 2009 4:12 am 
Newbie

Joined: Fri Aug 14, 2009 8:06 am
Posts: 19
Just for clarity, well it's a mystery to me, here is the stacktrace I get:
Code:
java.lang.OutOfMemoryError: Java heap space
   at java.util.Arrays.copyOf(Arrays.java:2882)
   at java.lang.AbstractStringBuilder.expandCapacity(AbstractStringBuilder.java:100)
   at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:390)
   at java.lang.StringBuffer.append(StringBuffer.java:224)
   at java.io.StringWriter.write(StringWriter.java:95)
   at java.io.PrintWriter.write(PrintWriter.java:412)
   at java.io.PrintWriter.write(PrintWriter.java:429)
   at java.io.PrintWriter.print(PrintWriter.java:559)
   at java.io.PrintWriter.println(PrintWriter.java:695)
   at java.lang.Throwable.printStackTraceAsCause(Throwable.java:538)
   at java.lang.Throwable.printStackTraceAsCause(Throwable.java:545)
   at java.lang.Throwable.printStackTraceAsCause(Throwable.java:545)
   at java.lang.Throwable.printStackTraceAsCause(Throwable.java:545)
   at java.lang.Throwable.printStackTraceAsCause(Throwable.java:545)
   at java.lang.Throwable.printStackTraceAsCause(Throwable.java:545)
   at java.lang.Throwable.printStackTraceAsCause(Throwable.java:545)
   at java.lang.Throwable.printStackTraceAsCause(Throwable.java:545)
   at java.lang.Throwable.printStackTraceAsCause(Throwable.java:545)
   at java.lang.Throwable.printStackTraceAsCause(Throwable.java:545)
   at java.lang.Throwable.printStackTraceAsCause(Throwable.java:545)
   at java.lang.Throwable.printStackTraceAsCause(Throwable.java:545)
   at java.lang.Throwable.printStackTraceAsCause(Throwable.java:545)
   at java.lang.Throwable.printStackTraceAsCause(Throwable.java:545)
   at java.lang.Throwable.printStackTraceAsCause(Throwable.java:545)
   at java.lang.Throwable.printStackTraceAsCause(Throwable.java:545)
   at java.lang.Throwable.printStackTraceAsCause(Throwable.java:545)
   at java.lang.Throwable.printStackTraceAsCause(Throwable.java:545)
   at java.lang.Throwable.printStackTraceAsCause(Throwable.java:545)
   at java.lang.Throwable.printStackTraceAsCause(Throwable.java:545)
   at java.lang.Throwable.printStackTraceAsCause(Throwable.java:545)
   at java.lang.Throwable.printStackTraceAsCause(Throwable.java:545)
   at java.lang.Throwable.printStackTraceAsCause(Throwable.java:545)


Top
 Profile  
 
 Post subject: Re: Out of memory error with 2 same calls in same session
PostPosted: Fri Oct 16, 2009 6:41 am 
Newbie

Joined: Fri Aug 14, 2009 8:06 am
Posts: 19
Ok, after a lot of fidgeting I managed to solve the problem. In the end it had something to do with an indexed transient object I forgot to save and a chicken and egg problem with the indexes themselves.

Cheers,
Stef


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.