Win a copy of The Little Book of Impediments (e-book only) this week in the Agile and Other Processes forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

JPA:I get cannot simultaneously fetch multiple bags when >=2 enteties FetchType.EAGER

 
Kenneth Gustafsson
Ranch Hand
Posts: 40
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
We're building a Java EE application which uses JPA through Hibernate. When trying to set fetch type to FetchType.EAGER on two @OneToMany relationships I get an exception saying: cannot simultaneously fetch multiple bags.

There is an article explaining this problem in more detail. Saying that it's possible to solve it by using @IndexColumn. However that's not an option for us as we don't want to get tied to Hibernate as our persistence provider.

Is there a way to solve this using pure JPA?
[ May 16, 2008: Message edited by: Kent Larsson ]
 
Mike Keith
author
Ranch Hand
Posts: 304
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You are using pure JPA. The problem is that your JPA provider has a major bug in it.

That's the beauty of the specification -- since you kept your code pure JPA you can now move on without being tied to any one vendor, so when you hit a showstopping bug you can try a different JPA provider that doesn't have that bug in it.
 
Rodrigo Lopes
Ranch Hand
Posts: 119
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You can configure one collection to have fecth type = EAGER and the second one to be LAZY. And then, implement the getter method for the LAZY one to actually retrieve the collection from database.
 
Kenneth Gustafsson
Ranch Hand
Posts: 40
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for your answer Mike and Rodrigo! That's the second time today both of you help me.

At the moment we try to work around the problem and stay with Hibernate. But we're trying to stick to pure JPA so that we can escape from Hibernate if we decide on it later on.

Worth mentioning is that they don't plan to correct this bug in Hibernate and say that they pass the Sun tests. They were not even friendly in their response to the user reporting the problem. (See the bug report on Hibernates bug tracking system.)

We're using SLSB's for our transactions and wanted to use the getters on the entities for presentation of information. As this presentation is done outside of a persistence session we're not allowed to get the LAZY data inside our POJO entity getter method.

If we wanted to use the getter method of our entity POJO we see two options.

The first is that it would have to call an SLSB and return the result through it. It means tying our POJO enteties to SLSB's by injecting the relevant SLSB in the POJO.

Our second option is to open a persistent context and do our database information retrieval from there. It means having database related code inside our entity POJO's.

What we do now is having no logic at all in our enteties. And doing all operations through SLSB's on them. Which means that instead of doing

we do

and the SLSB in turn does

and we get the result.
 
Mark Spritzler
ranger
Sheriff
Posts: 17278
6
IntelliJ IDE Mac Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Mike Keith:
You are using pure JPA. The problem is that your JPA provider has a major bug in it.

That's the beauty of the specification -- since you kept your code pure JPA you can now move on without being tied to any one vendor, so when you hit a showstopping bug you can try a different JPA provider that doesn't have that bug in it.


Bug is a little harsh words wouldn't you say.

If you think about it this way. Hibernate uses left outer joins when eager fetching a Collection. Therefore, if you have two of them, the most likely results will be a cartesian product. Hence the message from Hibernate to keep you from getting a resultset you don't want.

So, like a previous suggestion, is to eager fetch one and lazy or "subselect" fetch the second one when you need it.

Fetching really should be use case specific, so that you only bring down just the right amount of data and not bring down more than you need for that particular use case.

Mark
 
Joel Thompson
Greenhorn
Posts: 16
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Using hibernate as persistence impl, I solved this problem by declaring the 2nd one-to-many as a Set, and FetchType.LAZY, and then I created a query with "left join". When I needed to load the LAZY set, I just called the query. Also, notice that when you loop through the returned results, you are getting the cartesian product, thus, you get "many" of the one entities returned.
 
Cameron Wallace McKenzie
author and cow tipper
Saloon Keeper
Posts: 4968
1
Hibernate Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'm guessing that your query has multiple joins in it? That is the most common generator of this error. Here's an interesting thread from the Hibernate forums:

Multiple Joins in Many Association

-Cameron McKenzie
 
Micale Raj
Ranch Hand
Posts: 30
Hibernate IntelliJ IDE
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
try using FetchType.LAZY for all.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic