When using *session.byMulipleIds(SimpleEntity.class).multipleLoad(ids);* I got a few problems.
h2. *1. multiLoad 's sessionCheckingEnabled option default value should be true.*
If one of ids which managed entity by session should not be included in multiLoad query's 'in' condition.
{code:java} SimpleEntity third = session.byId( SimpleEntity.class ).load( 3 ); List<SimpleEntity> list = session.byMultipleIds(SimpleEntity.class) .multiLoad( Arrays.asList(1 , 2 , 3 )); assertEquals( 3, list.size() ); {code}
id "3" is already loaded in session that i expect query include only another ids "2", "3" ; like *session.byId(SimpleEntity.class).load(1);* But default value of sessionCheckingEnable is false that query include all ids even "1". It is more efficient i think.
If some of one wants to execute query include all ids like REFRESH it will be better. session.byMultipleIds(SimpleEntity.class).enableSessionCheck(false) .multiLoad( Arrays.asList(1 , 2 , 3 );
I fixed it in my forked repository. https://github.com/Myeonghyeon-Lee/hibernate-orm/commit/3e1b471a9d795b52aee930702856e7f06bf7eb00
h2. *2. Fix in multiLoad bugs with non flushed entities both side of sessionCheckingEnable true and false*
When sessionCheckingEnabled is true, *DynamicBatchingEntityLoaderBuilder* will check if some of ids are managed entities from session then they will exclude for query. But, below test will be failed.
{code:java} @Test public void testBasicMultiLoadWithManagedButRemovedAndChecking() { Session session = openSession(); session.getTransaction().begin(); SimpleEntity third = session.byId( SimpleEntity.class ).load( 3 ); session.remove(third); List<SimpleEntity> list = session.byMultipleIds(SimpleEntity.class).enableSessionCheck(true) .multiLoad( ids(56) ); // removed entity excluded in results assertEquals( 55, list.size() ); session.getTransaction().commit(); session.close(); } {code}
removed but non flushed entity will be founded by *DynamicBatchingEntityLoaderBuilder* that it will be excluded in query but included in results. I think it is a kind of bug. removed and non flushed entity should be excluded query and results. So *DynamicBatchingEntityLoaderBuilder* need to check if managedEntity marked DELETED or GONE.
When sessionCheckingEnabled is false, *DynamicBatchingEntityLoaderBuilder* should flush non flushed entity queries for consistence query results like executing HQL. (depends on FlushMode) Below test will be failed.
{code:java} @Test public void testBasicMultiLoadWithNonFlushedAndNoChecking() { Session session = openSession(); session.getTransaction().begin(); session.save( new SimpleEntity( 100, "Entity #" + 100 ) ); Integer[] ids = { 1, 2, 3, 100 }; List<SimpleEntity> list = session.byMultipleIds(SimpleEntity.class).enableSessionCheck(false) .multiLoad( ids ); // should include saved(non-flushed) entities in results depends on FlushMode assertEquals( 4, list.size() ); session.getTransaction().commit(); session.close(); } {code}
ids "1", "2", "3" are persisted but non managed entities, and id "100" saved before executing mulgiLoad(). id "100" of entity is managed in session but non flushed. When executing multiLoad() then results size is only 3 exclude "100". It is weird result with AutoFlush mode. If i use HQL query session will flush before executing query then result will correct. As a result, I think if sessionCheckingEnabled is false session flushed before executing multiLoad().
I fixed it in my forked repository. https://github.com/Myeonghyeon-Lee/hibernate-orm/commit/dc8c51a8ab38badc233277c4d84926d05a93c3ec
h2. *3. Enhance multiLoad test case*
When sessionCheckingEnabled is true that managed entities put in first position of results. But current both of test case tested by first entity and assert with first position of results. Given entity for right test will be another position of entity
I fixed it for enhancement of test https://github.com/Myeonghyeon-Lee/hibernate-orm/commit/4893a4835dfcaf5ee4d8512ea203b87bf9bfab29
It would be nice, if either these things apply in hibernate-orm Thanks. |
|