-->
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.  [ 8 posts ] 
Author Message
 Post subject: What am I doing wrong?
PostPosted: Wed Nov 22, 2006 10:24 am 
Newbie

Joined: Wed Nov 22, 2006 10:07 am
Posts: 6
Hello everyone,
I have this simple program which basically outputs data from a db (oracle 9) to a file. The db table is quite big (around 800k rows) and I get an OutOfMemoryError.
Below is the sample code that triggers the error; the error does not happen if I uncomment the line "emO.clear()".
It seems that the persistent objects don't get garbage collected without explicitly calling clear() on the EntityManager at every 1000 (or so) iterations.
This seems a little strange to me, because I would argue that the MerceologiaArticoloSic objects should be garbage collected when the flow exits the while loop.
Am I wrong on this? If yes, why?
Thanks in advance to everyone,
Riccardo

Hibernate version: 3.2 GA

Mapping documents: using Hibernate Annotations

Code between sessionFactory.openSession() and session.close():

EntityManager emO = emfOracle.createEntityManager();
PrintWriter out = new PrintWriter(new FileWriter("D:/temp/out.log"));
int maxResult = 1000;
int startResult = 0;
Query queryMerceologia = emO.createQuery("FROM MerceologiaArticoloSic");
queryMerceologia.setMaxResults(maxResult);
boolean over = false;
try {
while (!over) {
queryMerceologia.setFirstResult(startResult);
List<MerceologiaArticoloSic> res = queryMerceologia.getResultList();
for (MerceologiaArticoloSic merc : res) {
out.println(merc.toString());
}
over = (res.size() == 0);
startResult += maxResult;
log.info("inseriti "+startResult);
//emO.clear();
}
} catch (Exception e) {
log.error("Errore: " + e.getMessage(), e);
throw e;
} finally {
emO.close();
out.close();
}



Oracle 9


Top
 Profile  
 
 Post subject:
PostPosted: Wed Nov 22, 2006 11:10 am 
Senior
Senior

Joined: Fri May 14, 2004 9:37 am
Posts: 122
Location: Cologne, Germany
This depends on the settings you are using I would guess. You only read Data and don't write anything to the database so I guess the EntityManager caches your QueryResult, if you clear then the Cache should be invalid and cleared. For this reason it will not GarbageCollect the older objects because the reference is used/hold by the EntityManager and is only release if cleared.

_________________
regards

Olaf

vote if it helped


Top
 Profile  
 
 Post subject:
PostPosted: Wed Nov 22, 2006 12:49 pm 
Newbie

Joined: Wed Nov 22, 2006 10:07 am
Posts: 6
I didn't tweak with the cache settings; they all are default I suppose.
But even if caching is active, what's the point of caching until the process goes out of memory? It seems of no use to me to waste so much memory (I talk about hundreds of megabytes) to cache throwaway objects, which are created and dismissed in a very short period of time.
I never found anywhere a warning about having to use EntityManager.clear() if you use a long running session where you create lots of objects. Also I see no way to detach a single object after having used it (like in 'plain' hibernate).
By the way, here's what persistence.xml looks like (there are no hbm files because I used JPA annotations for orm):


<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
schemaLocation="http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
version="1.0">

<persistence-unit name="sic_oracle">
<description>Sic versione per Oracle</description>
<class><omitted>.importadati.entities.ArticoloSic</class>
<class><omitted>.importadati.entities.FormatoSic</class>
<class>
importadati.entities.MerceologiaArticoloSic
</class>
<class>importadati.entities.MerceologiaSic</class>
<properties>
<property name="hibernate.dialect"
value="org.hibernate.dialect.OracleDialect" />
<property name="hibernate.connection.driver_class"
value="oracle.jdbc.driver.OracleDriver">
</property>
<property name="hibernate.connection.username" value="<omitted>" />
<property name="hibernate.connection.password" value="<omitted>" />
<property name="hibernate.connection.url"
value="jdbc:oracle:thin:@<omitted>" />
</properties>
</persistence-unit>

</persistence>


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 23, 2006 1:38 pm 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
objects retrieved are in the persistence state, so the EM has to remember them in case you update them.

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Fri Nov 24, 2006 4:59 am 
Senior
Senior

Joined: Fri May 14, 2004 9:37 am
Posts: 122
Location: Cologne, Germany
Thx for explaining that in short terms ;)

_________________
regards

Olaf

vote if it helped


Top
 Profile  
 
 Post subject:
PostPosted: Fri Nov 24, 2006 5:31 am 
Newbie

Joined: Wed Nov 22, 2006 10:07 am
Posts: 6
Thanks Emmanuel,
it is the answer I was looking for.
Could someone post a warning on the docs about this? I mean, when you retrieve an object via EntityManager you end up with a "hidden" reference for wich you have no control other than using the clear() method which flushes all; this is different from the general rule for which an instance defined in a block only survives until the block's end.
Say, something in the getResults docs and/or tutorial which states clearly that all objects retrieved by the EM stay in memory until either the EM is closed or cleared or the instance is removed from persistence.
Thanks anyway,
Riccardo


Top
 Profile  
 
 Post subject:
PostPosted: Fri Nov 24, 2006 9:39 am 
Senior
Senior

Joined: Fri May 14, 2004 9:37 am
Posts: 122
Location: Cologne, Germany
How good that I gave you the same answer already in long terms and don't get the vote for it. Hell some of you guys are such rocket scientists.

_________________
regards

Olaf

vote if it helped


Top
 Profile  
 
 Post subject:
PostPosted: Fri Nov 24, 2006 10:38 am 
Newbie

Joined: Wed Nov 22, 2006 10:07 am
Posts: 6
Kaneda: that does NOT 'depend on the settings' as you wrote. It is like that 'by design' as Emmanuel wrote and that was the answer I was looking for.
Maybe my original post was not perfectly clear (english is not my first language) but it was about (as I explained later) the lack of a notable warning in the docs about what IMHO is a subtle pitfall in using EM.
To keep it short, the pattern is that you have to call EM.clear() after retrieving a certain amunt of objects: I don't like it but it is like that and it's not a bug.
I'm not a rocket scientist (I'm just a humble engineer) so I'm awarding you a credit too, even though your reply was not exactly what I wanted.
Regards and thanks for your help,
Riccardo


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 8 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.