views:

40

answers:

2

I have some OneToMany child collections in my domain classes that may grow over time to hold hundreds or (very likely) thousands of instances. However, often times the only thing the parent really needs is the "first" child or the "last" child or the "biggest" child. Having the parent instance loop through a large collection of objects loaded from the database seems inefficient.

On the other hand, I do not want to pollute my domain model with persistence concerns and start having to use my DAO's within the domain classes to execute queries.

I might potentially put these lookups in my service methods, but I really prefer to put this login in my domain where it belongs -- trying to avoid the "anaemic domain" anti-pattern.

Is there a way to pull just a "certain" object from a large collection without directly invoking the DAO? Some JPA ORM mapping capability I've overlooked?

Edit: The application is design in layers with the domain model layer at the bottom -- it depends on nothing else. Next to it is the persistence layer which implements DAOs and depends on the domain layer. Above both of them is a service layer which I am trying to keep as thin as possible by push business logic down into the domain layer.

+4  A: 

There are numerous options here

  1. Use lazy-loading or batch fetching
  2. Use HQL or Criteria queries or even drop down to native SQL to limit the number of results (in other words, instead of navigating the collection, do a query to return the N items you want)
  3. If caching is an option, you can likely avoid going to the database at least some of the time.
matt b
1. I'm already using lazy-loading though I can't imaging that buys me much given I have to always rifle through all the objects. 2. I can easily write the query I want and stick in a DAO. My question is then how and when does this get invoked, unless I create a circular dependency on my persistence layer from my domain layer.
HDave
Not sure if I understand your architecture so I can't really comment well - which layer is interfacing with the persistence layer today?
matt b
@matt b -- see edits to original question
HDave
+1  A: 

Is there a way to pull just a "certain" object from a large collection without directly invoking the DAO?

I'm not aware of a standard JPA feature allowing this and I think I would use custom queries here ("JPA doesn't deal well with large collections" is something you'll find everywhere).

Just in case, maybe have a look at some proprietary features such as:

I'm not sure the @Where annotation will be be that helpful (unless you create a special entity for the common use cases and a "fat" one). However, filters might be really interesting here. I've never used them tough.

Pascal Thivent
Hibernate filters are exactly what the doctor ordered, but I am still trying to keep the application 100% portable across JPA providers. Not sure how long I can hold out. Any way to do this without added hibernate stuff as a compile time dependency (right now it is a 100% runtime dependency).
HDave
@HDave: Yes, I can understand that (hence the first suggestion). But I thought it was worth mentioning that filters thing.
Pascal Thivent