[hibernate-issues] [Hibernate-JIRA] Commented: (HHH-5622) Criteria queries incorrectly retrieve associations on FetchMode.JOIN on scroll

Kyrill Alyoshin (JIRA) noreply at atlassian.com
Sat Oct 2 22:32:58 EDT 2010


    [ http://opensource.atlassian.com/projects/hibernate/browse/HHH-5622?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=38596#action_38596 ] 

Kyrill Alyoshin commented on HHH-5622:
--------------------------------------

Ouch... Just discovered that even with HQL Query (not Criteria), it doesn't work. What happens, is that the first Vendor (with two addresses) is processed correctly. The second Vendor (with two addresses) is processed incorrectly where its last address is not present in the scroll. In other words if you run a unit test in a loop, every Vendor (other than the first one) will be processed incorrectly with the second address dropped.

This is really sad, because now I have to resort to loading addresses for every Vendor in the main loop, n+1 select... 

> Criteria queries incorrectly retrieve associations on FetchMode.JOIN on scroll
> ------------------------------------------------------------------------------
>
>                 Key: HHH-5622
>                 URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-5622
>             Project: Hibernate Core
>          Issue Type: Bug
>          Components: core
>    Affects Versions: 3.5.4
>            Reporter: Kyrill Alyoshin
>
> I am really hesitant to submit this bug... It is hard to believe that this is actually happening, but...
> Basically, I am using Hibernate core 3.5.4 along with Hibernate Search 3.2.1. I opted to write my own re-indexer (as opposed to using MassIndexer). So, I have an entity called Vendor and it is in bi-directional One-To-Many relationship with an entity called VendorAddress (VendorAddres is not @Indexed).  I basically create a criteria query to retrieve all vendors and FetchMode.JOIN their addresses, and reindex them. Pretty straightforward stuff, just want the book "Hibernate Search in Action" says. Here is the code:
> {code}
> Criteria query = strategy.getQuery(session)
>                 .setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY)
>                 .setCacheMode(CacheMode.IGNORE)
>                 .setFetchSize(reindexBatchSize)
>                 .setFlushMode(FlushMode.MANUAL);
>         int loggingBatch = 1;
>         long loggingBatchStart = System.currentTimeMillis();
>         int counter = 1;
>         ScrollableResults cursor = null;
>         try {
>             cursor = query.scroll(ScrollMode.FORWARD_ONLY);
>             while (cursor.next()) {
>                 Vendor v = (Vendor) cursor.get(0);
>                 System.out.println("Addresses size is " + v.getAddresses().size());
>                 int count = 0;
>                 for (VendorAddress addr : v.getAddresses()) {
>                     count++;
>                     System.out.println("Address " + count + " is [" + addr + "]");
>                 }
>                 session.index(cursor.get(0));
>                 if (counter++ % reindexBatchSize == 0) {
>                     session.flushToIndexes();
>                     session.clear();
>                 }
>                 if (loggingBatch++ % loggingBatchSize == 0) {
>                     long stop = System.currentTimeMillis();
>                     logger.info("Re-indexed a batch of {} {} entities in {} millis. Total left to re-index: {}.",
>                             new Object[]{
>                                     loggingBatchSize, typeName,
>                                     (stop - loggingBatchStart), (totalCount - counter + 1)}
>                     );
>                     loggingBatchStart = stop;
>                 }
>             }
>             //don't delay to commit time, re-index what's left in a batch immediately
>             session.flushToIndexes();
>             session.clear();
>         }
>         finally {
>             //must be closed!
>             if (cursor != null) {
>                 cursor.close();
>             }
>         }
> {code}
> I have created a integration test that basically creates a Vendor with two addresses, saves it, and re-indexes it. But what happens is that when the scroll runs, it correctly detected that there are two records for Vendor (because of a join) but always retrieves the first address twice!!! Here is the log output from the code above:
> {code}
> Hibernate: 
>     /* criteria query */ select
>         this_.vendor_id as vendor1_21_1_,
>         this_.created_by as created2_21_1_,
>         this_.created_date as created3_21_1_,
>         this_.last_modified_by as last4_21_1_,
>         this_.last_modified_date as last5_21_1_,
>         this_.centralized_ar_flag as centrali6_21_1_,
>         this_.enrollment_specialist_id as enrollment9_21_1_,
>         this_.pm_company_id as pm7_21_1_,
>         this_.name as name21_1_,
>         addresses2_.vendor_id as vendor17_21_3_,
>         addresses2_.addr_id as addr2_3_,
>         addresses2_.addr_id as addr2_13_0_,
>         addresses2_.created_by as created3_13_0_,
>         addresses2_.created_date as created4_13_0_,
>         addresses2_.last_modified_by as last5_13_0_,
>         addresses2_.last_modified_date as last6_13_0_,
>         addresses2_.city as city13_0_,
>         addresses2_.country_code as country8_13_0_,
>         addresses2_.addr_line_1 as addr9_13_0_,
>         addresses2_.addr_line_2 as addr10_13_0_,
>         addresses2_.addr_line_3 as addr11_13_0_,
>         addresses2_.postal_code as postal12_13_0_,
>         addresses2_.state_province_code as state13_13_0_,
>         addresses2_.vendor_id as vendor17_13_0_,
>         addresses2_.verified_flag as verified15_13_0_ 
>     from
>         mktg.vendor this_ 
>     left outer join
>         mktg.address addresses2_ 
>             on this_.vendor_id=addresses2_.vendor_id
> Addresses size is 1
> Address 1 is [[VendorAddress at 10a063d id = 1]]
> Addresses size is 1
> Address 1 is [[VendorAddress at 10a063d id = 1]]
> {code}
> So, basically the second address is out of the picture.
> Now... The workaround... If I use a simple HQL query and do the same scrolling thing, everything works beautifully:
> "from Vendor v left outer join v.addresses"
> I believe this to be a critical bug in how Criteria queries handle scrolling. 

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://opensource.atlassian.com/projects/hibernate/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        


More information about the hibernate-issues mailing list