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

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


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