2

I've got a Vehicle entity, with a Vehicle DTO.

I use OpenSessionInView with Stripes.

In my Stripes action bean, i need to generate a csv containing the data for about 50000 Vehicles.

Thus, as a Stripes developer told me to do, i write the file to the outputstream in the following method:

StreamingResolution() {...}.stream(HttpServletResponse)

I have a service that take some pagination information, load a part of the vehicles and transform them into DTO's.

These dto's are returned to the view and written to the csv.

The pagination system (500 items for each page) was made to avoid having a list of 50000 DTO and have some memory problems.

But it doesn't work perfectly yet. With Jmap i saw that at the end of the csv process, there are more than 40000 vehicules loaded in heap space and not garbage collected.

With Yourkit profiler, it seems to me that these entities are still in the L1 cache of hibernate (referenced in StatefulPersistenceContext), and since i have OpenSessionInView, i guess the problem is that the conversation is a bit long and the cache need to be cleaned...

I just wonder how to do that in an elegant way since my dao methods loading vehicles are used by a lot of services that doesn't necessary need a session clean/flush.

Someone know i could do? I guess i can make a method in the DAO/Service to clear the session but it's not very elegant...

This is a pretty big project and i made a very simple description of it. Please don't tell me to not use opensessioninview or something like that, it's not my decision... ;)

DataNucleus
  • 15,199
  • 3
  • 30
  • 37
Sebastien Lorber
  • 79,294
  • 59
  • 260
  • 386
  • 1
    Is there a way to do something like closing the session after a service call on my view layer and reopen a new session for a new service call? I mean isn't there a way to do, on some service calls only, like if there was no OpenSessionInView filter, while there is one? – Sebastien Lorber Jan 21 '11 at 13:54
  • Yes there is - post up some code that shows how you interact with hibernate. – Pablojim Jan 21 '11 at 17:22
  • I just use spring hibernate template in daos – Sebastien Lorber Jan 22 '11 at 12:38

3 Answers3

4

It may not be elegant, but in cases like this evicting entities from the session is the only practical solution.

For example, once you've finished writing an entity's data to the output stream, call session.evict(entity) to remove it from the session cache. Alternatively, call this at the end of each "page".

The combination of the paging mechanism and the eviction should ensure you never have more than 500 entities in the cache at one time.

skaffman
  • 381,978
  • 94
  • 789
  • 754
  • The matter is that i don't have access to the spring hibernate template so it's almost the same: i'll have to make a dao method just to evict an entity? – Sebastien Lorber Jan 21 '11 at 13:32
4

Evicting objects is elegant and it is the only good solution when doing reports, exports to CSV etc.

The best elegant way is to implement it inside a service, which will open iterator, evict each item after process. The class would be provided for service call, that would be item consumer.

public interface ItemConsumer { void consume(Item item); }

public void processAllItems(ItemConsumer consumer) {

.. do your job }

FolksLord
  • 932
  • 2
  • 9
  • 16
3

You probably want to explicitly open a stateless session.

e.g.

StatelessSession session = sessionFactory.openStatelessSession();

From the docs:

A StatelessSession has no persistence context associated with it and does not provide many of the higher-level life cycle semantics. In particular, a stateless session does not implement a first-level cache nor interact with any second-level or query cache. It does not implement transactional write-behind or automatic dirty checking

See here for more details:

http://docs.jboss.org/hibernate/core/3.3/reference/en/html/batch.html

Pablojim
  • 8,092
  • 8
  • 41
  • 66
  • Nice to know but i use Spring and a StatelessHibernateCallback was introduced in 3.0 only (i have 2.5) – Sebastien Lorber Jan 21 '11 at 13:46
  • You still should be able to get a handle on the underlying SessionFactory. Post up some more details of the exact situation (and hibernate version) and I'll see if I can help. – Pablojim Jan 21 '11 at 15:19