Is it valid for Hibernate list() to return duplicates?
Asked Answered
D

4

30

Is anyone aware of the validity of Hibernate's Criteria.list() and Query.list() methods returning multiple occurrences of the same entity?

Occasionally I find when using the Criteria API, that changing the default fetch strategy in my class mapping definition (from "select" to "join") can sometimes affect how many references to the same entity can appear in the resulting output of list(), and I'm unsure whether to treat this as a bug or not. The javadoc does not define it, it simply says "The list of matched query results." (thanks guys).

If this is expected and normal behaviour, then I can de-dup the list myself, that's not a problem, but if it's a bug, then I would prefer to avoid it, rather than de-dup the results and try to ignore it.

Anyone got any experience of this?

Deuteragonist answered 13/10, 2009 at 13:25 Comment(0)
M
24

Yes, getting duplicates is perfectly possible if you construct your queries so that this can happen. See for example Hibernate CollectionOfElements EAGER fetch duplicates elements

Mulcahy answered 13/10, 2009 at 13:34 Comment(4)
+1. How can I not upvote someone linking to my answer? :-) Seriously, however - yes, Hibernate may return duplicates when more than one "to-many" association is either declared with eager fetch or retrieved using join fetch within the same query. Look at the note at the bottom of 14.3: docs.jboss.org/hibernate/stable/core/reference/en/html/…Sharmainesharman
Thanks for the doc link, I knew it had to be in there somewhereDeuteragonist
@Sharmainesharman The link is broken!Languishment
updated link: docs.jboss.org/hibernate/orm/4.2/manual/en-US/html/…Anything
B
6

I also started noticing this behavior in my Java API as it started to grow. Glad there is an easy way to prevent it. Out of practice I've started out appending:

.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)

To all of my criteria that return a list. For example:

List<PaymentTypeAccountEntity> paymentTypeAccounts = criteria()
  .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
  .list();
Bangtail answered 26/8, 2016 at 16:14 Comment(0)
C
4

If you have an object which has a list of sub objects on it, and your criteria joins the two tables together, you could potentially get duplicates of the main object.

One way to ensure that you don't get duplicates is to use a DistinctRootEntityResultTransformer. The main drawback to this is if you are using result set buffering/row counting. The two don't work together.

Cowhide answered 14/4, 2010 at 0:18 Comment(0)
L
0

I had the exact same issue with Criteria API. The simple solution for me was to set distinct to true on the query like

CriteriaQuery<Foo> query = criteriaBuilder.createQuery(Foo.class);
query.distinct(true);

Another possible option that came to my mind before would be to simply pass the resulting list to a Set which will also by definition have just an object's single instance.

Littlefield answered 13/11, 2018 at 9:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.