| Summary: | query with batch reading returns wrong results after flush | ||||||
|---|---|---|---|---|---|---|---|
| Product: | z_Archived | Reporter: | john.vandale | ||||
| Component: | Eclipselink | Assignee: | Nobody - feel free to take it <nobody> | ||||
| Status: | RESOLVED FIXED | QA Contact: | |||||
| Severity: | normal | ||||||
| Priority: | P3 | CC: | david.minsky, john.vandale, peter.krogh | ||||
| Version: | unspecified | ||||||
| Target Milestone: | --- | ||||||
| Hardware: | All | ||||||
| OS: | All | ||||||
| Whiteboard: | |||||||
| Attachments: |
|
||||||
Created attachment 179549 [details]
addition to javadoc for eclipselink.batch query hint
This behavior is the way it works. Its the user's responsibility not to change and flush data that would effect the query conditions prior to referencing the results of the query. The uploaded patch provides javadoc to explain this behavior. Fixed in r8247 (trunk - representing 2.2) The Eclipselink project has moved to Github: https://github.com/eclipse-ee4j/eclipselink The Eclipselink project has moved to Github: https://github.com/eclipse-ee4j/eclipselink |
Build Identifier: A query for a relationship mapping defined with batch reading would return invalid results, if changes had been performed on the object graph of the parent which would change the results of the query on the parent, if such changes had been flushed before triggering the batch reading query. Entity Object Model ----------------------- HouseBO has a OneToOneMapping to GarageBO HouseBO has a OneToManyMapping to WindowBO Problem Scenario --------------------- public void test() throws Exception { JpaEntityManager entityManager = JpaHelper.getEntityManager(persistenceContext); entityManager.getTransaction().begin(); Session session = JpaHelper.getEntityManager(persistenceContext).getActiveSession(); ReadAllQuery query = new ReadAllQuery(); query.setReferenceClass(HouseBO.class); Expression filter = query.getExpressionBuilder(); filter = filter.getAllowingNull("garage").get("name").equal("G1"); query.setSelectionCriteria(filter); Expression expressionFetch = query.getExpressionBuilder(); expressionFetch = expressionFetch.getAllowingNull("window"); query.addBatchReadAttribute(expressionFetch); List< HouseBO > result = (List< HouseBO >) session.executeQuery(query); assertEquals("Incorrect House result set size.", 1, result.size()); HouseBO house = result.get(0); house.setGarage(null); entityManager.flush(); assertEquals("Incorrect Window result set size.", 3, result.get(0).getWindow().size()); } Observed Behavior ------------------------ The second assertEquals will fail because the batch reading query generated would incorporate the query that had been executed for the parent. This query would check for the garage but the association with the Garage had been removed from the house. SELECT t0.ID, t0.AENDERUNGSZEITPUNKT, t0.NAME, t0.LOESCHKZ, t0.VERSION, t0.FK_HOUSE_WINDOW FROM HOUSE t1 LEFT OUTER JOIN GARAGE t2 ON (t2.ID = t1.FK_GARAGE_HOUSE), WINDOW t0 WHERE ((t0.FK_HOUSE_WINDOW = t1.ID) AND (t2.NAME = ?)) bind => [G1] Expected Behavior ----------------------- 1. Batch reading should be switched off if the entity context was flushed and the transaction is still active. or 2. All relation ship mappings configured with batch reading should be triggered when flush is been called on the entity context. or 3. Batch reading should be switched off if changes performed on the object graph of the parent would affect the result of the query performed to obtain the parent object. Note: Just referencing the indirect collection prior to the flush prevents this from happening. For example: List< HouseBO > result = (List< HouseBO >) session.executeQuery(query); assertEquals("Incorrect House result set size.", 1, result.size()); HouseBO house = result.get(0); result.get(0).getWindow().size() // line added just to trigger loading house.setGarage(null); entityManager.flush(); assertEquals("Incorrect Window result set size.", 3, result.get(0).getWindow().size()); In this case the 2nd assert does not fail as the size of the windows set returned is 3 not null. Reproducible: Always