6

I am writing a very simple query, but I am getting duplicate values for some reason.

Criteria cr = session.createCriteria(ProcessInstance.class, "p")
        .add(Restrictions.isNull("end"));
@Cleanup ScrollableResults sr = cr.scroll(ScrollMode.FORWARD_ONLY);

while (sr.next()) {
    pi = (ProcessInstance) sr.get(0);
    String id = pi.getId(); //Getting duplicate values
}

The pi.getId() returns duplicate values. ie: *9,9,10,10,11,11 etc*

However, running this query directly in mysql

SELECT * FROM JBPM_PROCESSINSTANCE J where J.END_ IS NULL

Does not return duplicate values.

Can anyone spot what is wrong?

Shervin Asgari
  • 23,001
  • 29
  • 97
  • 141

2 Answers2

18

The fast workarround would be to use a Distinct Root Entity Result Transformer.

...
crit.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
List unique = crit.List();
...

But this is only a workarround.

I ques the problem belongs to your mapping. If there is any eager loaded 1:n relationship from ProcessInstance to something else (call it X), and there are several (n) X for one ProcessInstance, the you will get several ProcessInstance items (n) in the result list for a single ProcessInstance. -- If this is realy the cause, than the workarround is not just a workarround, then it would be the solution.

Ralph
  • 115,440
  • 53
  • 279
  • 370
  • Yes this is right. We changed mapping to be fetch eager. Thanks – Shervin Asgari Jan 10 '11 at 10:29
  • This didn't help. We still get duplicates. Does the resultTransformer only work with List()? We are using scroll. – Shervin Asgari Jan 10 '11 at 10:38
  • You understand me wrong: the problem can occure if the relation IS fetched egger - change it to lazy. – Ralph Jan 10 '11 at 10:46
  • I cannot change it to lazy. We must have eager because of another bug in jbpm/seam. Is there some other workaround? I can also report that your solution worked using `list()`. However, I am looking for a solution using `scroll` – Shervin Asgari Jan 10 '11 at 10:50
  • Is this case the result transtransformer is the only solution i know - But it needs to load all entites first, and this is why scroll does not work. – Ralph Jan 10 '11 at 11:08
  • The only hack I know to implemnt scolling like you need, is to fetch only the IDs with the first query using DISTINCT_ROOT_ENTITY, and then load the real entities with an second Scrollable query by its ID's -- But if this increase your performance strongly depends on your use case. – Ralph Jan 10 '11 at 11:11
  • I have same problem but this solution doesn't help me. http://stackoverflow.com/questions/33127626/criteria-distinct-root-entity-doesnt-prevent-duplicated-objects – gstackoverflow Oct 14 '15 at 14:15
2

I encouter the same problem as you..

This is how I solve it.

Criteria cr = session.createCriteria(ProcessInstance.class, "p")
        .add(Restrictions.isNull("end")).setProjection("id")

this will returns all the ID that satisfy all your criteria.

there after you use In restrictions and perform CriteriaSpecification.DISTINCT_ROOT_ENTITY.

You will be able to scroll your result in 2nd criteria.. I hope this help.

Shervin Asgari
  • 23,001
  • 29
  • 97
  • 141
seesee
  • 1,135
  • 5
  • 18
  • 45