diff --git a/hibernate-core/src/main/java/org/hibernate/IncludeRemovals.java b/hibernate-core/src/main/java/org/hibernate/IncludeRemovals.java
new file mode 100644
index 000000000000..243225a1a3e5
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/IncludeRemovals.java
@@ -0,0 +1,31 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ * Copyright Red Hat Inc. and Hibernate Authors
+ */
+package org.hibernate;
+
+
+import jakarta.persistence.EntityGraph;
+import jakarta.persistence.FindOption;
+
+import java.util.List;
+
+/**
+ * MultiFindOption implementation to specify whether the returned list
+ * of entity instances should contain instances that have been
+ * {@linkplain Session#remove(Object) marked for removal} in the
+ * current session, but not yet deleted in the database.
+ *
+ * The default is {@link #EXCLUDE}, meaning that instances marked for
+ * removal are replaced by null in the returned list of entities when {@link OrderedReturn}
+ * is used.
+ *
+ * @see org.hibernate.MultiFindOption
+ * @see OrderedReturn
+ * @see org.hibernate.Session#findMultiple(Class, List, FindOption...)
+ * @see org.hibernate.Session#findMultiple(EntityGraph, List , FindOption...)
+ */
+public enum IncludeRemovals implements MultiFindOption {
+ INCLUDE,
+ EXCLUDE
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/MultiFindOption.java b/hibernate-core/src/main/java/org/hibernate/MultiFindOption.java
new file mode 100644
index 000000000000..400f7b9354ad
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/MultiFindOption.java
@@ -0,0 +1,14 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ * Copyright Red Hat Inc. and Hibernate Authors
+ */
+package org.hibernate;
+
+
+import jakarta.persistence.FindOption;
+
+/**
+ * Simple marker interface for FindOptions which can be applied to multiple id loading.
+ */
+public interface MultiFindOption extends FindOption {
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/MultiIdentifierLoadAccess.java b/hibernate-core/src/main/java/org/hibernate/MultiIdentifierLoadAccess.java
index 0d33cbff22db..2b5f850ff4b3 100644
--- a/hibernate-core/src/main/java/org/hibernate/MultiIdentifierLoadAccess.java
+++ b/hibernate-core/src/main/java/org/hibernate/MultiIdentifierLoadAccess.java
@@ -31,7 +31,11 @@
* @see Session#byMultipleIds(Class)
*
* @author Steve Ebersole
+
+ * @deprecated Use forms of {@linkplain Session#findMultiple} accepting
+ * {@linkplain jakarta.persistence.FindOption} instead of {@linkplain Session#byMultipleIds}.
*/
+@Deprecated(since = "7.2", forRemoval = true)
public interface MultiIdentifierLoadAccess {
/**
diff --git a/hibernate-core/src/main/java/org/hibernate/OrderedReturn.java b/hibernate-core/src/main/java/org/hibernate/OrderedReturn.java
new file mode 100644
index 000000000000..5ba775c590ab
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/OrderedReturn.java
@@ -0,0 +1,32 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ * Copyright Red Hat Inc. and Hibernate Authors
+ */
+package org.hibernate;
+
+
+import jakarta.persistence.EntityGraph;
+import jakarta.persistence.FindOption;
+
+import java.util.List;
+
+/**
+ * MultiFindOption implementation to specify whether the returned list
+ * of entity instances should be ordered, where the position of an entity
+ * instance is determined by the position of its identifier
+ * in the list of ids passed to {@code findMultiple(...)}.
+ *
+ * The default is {@link #ORDERED}, meaning the positions of the entities
+ * in the returned list correspond to the positions of their ids. In this case,
+ * the {@link IncludeRemovals} handling of entities marked for removal
+ * becomes important.
+ *
+ * @see org.hibernate.MultiFindOption
+ * @see IncludeRemovals
+ * @see org.hibernate.Session#findMultiple(Class, List, FindOption...)
+ * @see org.hibernate.Session#findMultiple(EntityGraph, List , FindOption...)
+ */
+public enum OrderedReturn implements MultiFindOption {
+ ORDERED,
+ UNORDERED
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/Session.java b/hibernate-core/src/main/java/org/hibernate/Session.java
index abc2c2f3eec6..8d925c331240 100644
--- a/hibernate-core/src/main/java/org/hibernate/Session.java
+++ b/hibernate-core/src/main/java/org/hibernate/Session.java
@@ -1165,7 +1165,12 @@ public interface Session extends SharedSessionContract, EntityManager {
* @throws HibernateException If the given class does not resolve as a mapped entity
*
* @see #findMultiple(Class, List, FindOption...)
+ *
+ * @deprecated This method will be removed.
+ * Use {@link #findMultiple(Class, List, FindOption...)} instead.
+ * See {@link MultiFindOption}.
*/
+ @Deprecated(since = "7.2", forRemoval = true)
MultiIdentifierLoadAccess byMultipleIds(Class entityClass);
/**
@@ -1177,7 +1182,12 @@ public interface Session extends SharedSessionContract, EntityManager {
* @return an instance of {@link MultiIdentifierLoadAccess} for executing the lookup
*
* @throws HibernateException If the given name does not resolve to a mapped entity
+ *
+ * @deprecated This method will be removed.
+ * Use {@link #findMultiple(Class, List, FindOption...)} instead.
+ * See {@link MultiFindOption}.
*/
+ @Deprecated(since = "7.2", forRemoval = true)
MultiIdentifierLoadAccess byMultipleIds(String entityName);
/**
diff --git a/hibernate-core/src/main/java/org/hibernate/SessionChecking.java b/hibernate-core/src/main/java/org/hibernate/SessionChecking.java
new file mode 100644
index 000000000000..37757af3655d
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/SessionChecking.java
@@ -0,0 +1,30 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ * Copyright Red Hat Inc. and Hibernate Authors
+ */
+package org.hibernate;
+
+
+import jakarta.persistence.EntityGraph;
+import jakarta.persistence.FindOption;
+
+import java.util.List;
+
+/**
+ * MultiFindOption implementation to specify whether the ids of managed entity instances already
+ * cached in the current persistence context should be excluded.
+ * from the list of ids sent to the database.
+ *
+ * The default is {@link #DISABLED}, meaning all ids are included and sent to the database.
+ *
+ * Use {@link #ENABLED} to exclude already managed entity instance ids from
+ * the list of ids sent to the database.
+ *
+ * @see org.hibernate.MultiFindOption
+ * @see org.hibernate.Session#findMultiple(Class, List , FindOption...)
+ * @see org.hibernate.Session#findMultiple(EntityGraph, List , FindOption...)
+ */
+public enum SessionChecking implements MultiFindOption {
+ ENABLED,
+ DISABLED
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/internal/SessionImpl.java b/hibernate-core/src/main/java/org/hibernate/internal/SessionImpl.java
index c48197058fd7..550560ee94f1 100644
--- a/hibernate-core/src/main/java/org/hibernate/internal/SessionImpl.java
+++ b/hibernate-core/src/main/java/org/hibernate/internal/SessionImpl.java
@@ -964,6 +964,15 @@ else if ( option instanceof ReadOnlyMode ) {
else if ( option instanceof BatchSize batchSizeOption ) {
batchSize = batchSizeOption.batchSize();
}
+ else if ( option instanceof SessionChecking sessionChecking ) {
+ loadAccess.enableSessionCheck( option == sessionChecking.ENABLED );
+ }
+ else if ( option instanceof OrderedReturn orderedReturn ) {
+ loadAccess.enableOrderedReturn( option == orderedReturn.ORDERED );
+ }
+ else if ( option instanceof IncludeRemovals includeRemovals ) {
+ loadAccess.enableReturnOfDeletedEntities( option == includeRemovals.INCLUDE );
+ }
}
loadAccess.with( lockOptions )
.with( interpretCacheMode( storeMode, retrieveMode ) )
@@ -2291,6 +2300,9 @@ else if ( option instanceof EnabledFetchProfile enabledFetchProfile ) {
else if ( option instanceof ReadOnlyMode ) {
loadAccess.withReadOnly( option == ReadOnlyMode.READ_ONLY );
}
+ else if ( option instanceof MultiFindOption multiFindOption ) {
+ throw new IllegalArgumentException( "Option '" + multiFindOption + "' can only be used in 'findMultiple()'" );
+ }
}
if ( lockOptions.getLockMode().isPessimistic() ) {
if ( lockOptions.getTimeOut() == WAIT_FOREVER_MILLI ) {
diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/dynamicmap/FindOperationTests.java b/hibernate-core/src/test/java/org/hibernate/orm/test/dynamicmap/FindOperationTests.java
index 4b7e77ec858e..d2b6069a8da8 100644
--- a/hibernate-core/src/test/java/org/hibernate/orm/test/dynamicmap/FindOperationTests.java
+++ b/hibernate-core/src/test/java/org/hibernate/orm/test/dynamicmap/FindOperationTests.java
@@ -4,7 +4,10 @@
*/
package org.hibernate.orm.test.dynamicmap;
+import org.hibernate.IncludeRemovals;
+import org.hibernate.OrderedReturn;
import org.hibernate.ReadOnlyMode;
+import org.hibernate.SessionChecking;
import org.hibernate.graph.RootGraph;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.SessionFactory;
@@ -17,6 +20,7 @@
import java.util.Map;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertThrows;
/**
* @author Steve Ebersole
@@ -58,6 +62,15 @@ void testFindWithOptions(SessionFactoryScope factoryScope) {
} );
}
+ @Test
+ void testFindWithIllegalOptions(SessionFactoryScope factoryScope) {
+ factoryScope.inTransaction( (session) -> {
+ assertThrows( IllegalArgumentException.class, () ->session.find( "artist", 1, SessionChecking.ENABLED ) );
+ assertThrows( IllegalArgumentException.class, () ->session.find( "artist", 1, OrderedReturn.ORDERED ) );
+ assertThrows( IllegalArgumentException.class, () ->session.find( "artist", 1, IncludeRemovals.INCLUDE ) );
+ } );
+ }
+
@Test
void testFindWithGraph(SessionFactoryScope factoryScope) {
factoryScope.inTransaction( (session) -> {
diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/loading/multiLoad/MultiLoadTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/loading/multiLoad/MultiLoadTest.java
index d4174d6a13bf..fa143411e7b4 100644
--- a/hibernate-core/src/test/java/org/hibernate/orm/test/loading/multiLoad/MultiLoadTest.java
+++ b/hibernate-core/src/test/java/org/hibernate/orm/test/loading/multiLoad/MultiLoadTest.java
@@ -4,11 +4,15 @@
*/
package org.hibernate.orm.test.loading.multiLoad;
+import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import org.hibernate.CacheMode;
import org.hibernate.Hibernate;
+import org.hibernate.IncludeRemovals;
+import org.hibernate.OrderedReturn;
+import org.hibernate.SessionChecking;
import org.hibernate.annotations.BatchSize;
import org.hibernate.cache.spi.access.AccessType;
import org.hibernate.cfg.AvailableSettings;
@@ -37,13 +41,13 @@
import jakarta.persistence.Table;
import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* @author Steve Ebersole
@@ -86,7 +90,7 @@ public void testBasicMultiLoad(SessionFactoryScope scope) {
final SQLStatementInspector statementInspector = scope.getCollectingStatementInspector();
scope.inTransaction(
session -> {
- statementInspector.getSqlQueries().clear();
+ statementInspector.clear();
List list = session.byMultipleIds( SimpleEntity.class ).multiLoad( ids( 5 ) );
assertEquals( 5, list.size() );
@@ -214,10 +218,18 @@ public void testDuplicatedRequestedIdswithDisableOrderedReturn(SessionFactorySco
scope.inTransaction(
session -> {
// un-ordered multiLoad
- List list = session.byMultipleIds( SimpleEntity.class )
- .enableOrderedReturn( false )
- .multiLoad( 1, 2, 3, 2, 2 );
- assertEquals( 3, list.size() );
+ {
+ final List list = session.byMultipleIds( SimpleEntity.class )
+ .enableOrderedReturn( false )
+ .multiLoad( 1, 2, 3, 2, 2 );
+ assertEquals( 3, list.size() );
+ }
+
+ {
+ final List list = session.findMultiple( SimpleEntity.class, List.of( 1, 2, 3, 2, 2 ), OrderedReturn.UNORDERED );
+ assertEquals( 3, list.size() );
+
+ }
}
);
}
@@ -228,13 +240,20 @@ public void testNonExistentIdRequest(SessionFactoryScope scope) {
scope.inTransaction(
session -> {
// ordered multiLoad
- List list = session.byMultipleIds( SimpleEntity.class ).multiLoad( 1, 699, 2 );
- assertEquals( 3, list.size() );
- assertNull( list.get( 1 ) );
+ {
+ List list = session.byMultipleIds( SimpleEntity.class ).multiLoad( 1, 699, 2 );
+ assertEquals( 3, list.size() );
+ assertNull( list.get( 1 ) );
+
+ // un-ordered multiLoad
+ list = session.byMultipleIds( SimpleEntity.class ).enableOrderedReturn( false ).multiLoad( 1, 699, 2 );
+ assertEquals( 2, list.size() );
+ }
- // un-ordered multiLoad
- list = session.byMultipleIds( SimpleEntity.class ).enableOrderedReturn( false ).multiLoad( 1, 699, 2 );
- assertEquals( 2, list.size() );
+ {
+ final List list = session.findMultiple( SimpleEntity.class, List.of(1, 699, 2), OrderedReturn.UNORDERED );
+ assertEquals( 2, list.size() );
+ }
}
);
}
@@ -257,14 +276,26 @@ public void testBasicMultiLoadWithManagedAndNoChecking(SessionFactoryScope scope
public void testBasicMultiLoadWithManagedAndChecking(SessionFactoryScope scope) {
scope.inTransaction(
session -> {
- SimpleEntity first = session.byId( SimpleEntity.class ).load( 1 );
- List list = session.byMultipleIds( SimpleEntity.class )
- .enableSessionCheck( true )
- .multiLoad( ids( 56 ) );
- assertEquals( 56, list.size() );
- // this check is HIGHLY specific to implementation in the batch loader
- // which puts existing managed entities first...
- assertSame( first, list.get( 0 ) );
+ SimpleEntity first;
+ {
+ final List list;
+ first = session.byId( SimpleEntity.class ).load( 1 );
+ list = session.byMultipleIds( SimpleEntity.class )
+ .enableSessionCheck( true )
+ .multiLoad( ids( 56 ) );
+ assertEquals( 56, list.size() );
+ // this check is HIGHLY specific to implementation in the batch loader
+ // which puts existing managed entities first...
+ assertSame( first, list.get( 0 ) );
+ }
+
+ {
+ final List list = session.findMultiple( SimpleEntity.class, idList(56), SessionChecking.ENABLED );
+ assertEquals( 56, list.size() );
+ // this check is HIGHLY specific to implementation in the batch loader
+ // which puts existing managed entities first...
+ assertSame( first, list.get( 0 ) );
+ }
}
);
}
@@ -288,13 +319,26 @@ public void testBasicMultiLoadWithManagedAndCheckingProxied(SessionFactoryScope
scope.inTransaction(
session -> {
SimpleEntity first = session.byId( SimpleEntity.class ).getReference( 1 );
- List list = session.byMultipleIds( SimpleEntity.class )
- .enableSessionCheck( true )
- .multiLoad( ids( 56 ) );
- assertEquals( 56, list.size() );
- // this check is HIGHLY specific to implementation in the batch loader
- // which puts existing managed entities first...
- assertSame( first, list.get( 0 ) );
+ {
+ final List list = session.byMultipleIds( SimpleEntity.class )
+ .enableSessionCheck( true )
+ .multiLoad( ids( 56 ) );
+ assertEquals( 56, list.size() );
+ // this check is HIGHLY specific to implementation in the batch loader
+ // which puts existing managed entities first...
+ assertSame( first, list.get( 0 ) );
+ }
+
+ session.evict( first );
+ first = session.byId( SimpleEntity.class ).getReference( 1 );
+
+ {
+ final List list = session.findMultiple( SimpleEntity.class, idList(56), SessionChecking.ENABLED );
+ assertEquals( 56, list.size() );
+ // this check is HIGHLY specific to implementation in the batch loader
+ // which puts existing managed entities first...
+ assertSame( first, list.get( 0 ) );
+ }
}
);
}
@@ -330,31 +374,59 @@ public void testMultiLoadFrom2ndLevelCache(SessionFactoryScope scope) {
// Validate that the entity is still in the Level 2 cache
assertTrue( session.getSessionFactory().getCache().containsEntity( SimpleEntity.class, 2 ) );
- statementInspector.getSqlQueries().clear();
-
- // Multiload 3 items and ensure that multiload pulls 2 from the database & 1 from the cache.
- List entities = session.byMultipleIds( SimpleEntity.class )
- .with( CacheMode.NORMAL )
- .enableSessionCheck( true )
- .multiLoad( ids( 3 ) );
- assertEquals( 3, entities.size() );
- assertEquals( 1, statistics.getSecondLevelCacheHitCount() );
-
- for(SimpleEntity entity: entities) {
- assertTrue( session.contains( entity ) );
+ statementInspector.clear();
+ {
+ // Multiload 3 items and ensure that multiload pulls 2 from the database & 1 from the cache.
+ final List entities = session.byMultipleIds( SimpleEntity.class )
+ .with( CacheMode.NORMAL )
+ .enableSessionCheck( true )
+ .multiLoad( ids( 3 ) );
+ assertEquals( 3, entities.size() );
+ assertEquals( 1, statistics.getSecondLevelCacheHitCount() );
+
+ for ( SimpleEntity entity : entities ) {
+ assertTrue( session.contains( entity ) );
+ }
+
+ final int paramCount = StringHelper.countUnquoted(
+ statementInspector.getSqlQueries().get( 0 ),
+ '?'
+ );
+
+ final Dialect dialect = session.getSessionFactory().getJdbcServices().getDialect();
+ if ( MultiKeyLoadHelper.supportsSqlArrayType( dialect ) ) {
+ assertThat( paramCount, is( 1 ) );
+ }
+ else {
+ assertThat( paramCount, is( 2 ) );
+ }
}
- final int paramCount = StringHelper.countUnquoted(
- statementInspector.getSqlQueries().get( 0 ),
- '?'
- );
-
- final Dialect dialect = session.getSessionFactory().getJdbcServices().getDialect();
- if ( MultiKeyLoadHelper.supportsSqlArrayType( dialect ) ) {
- assertThat( paramCount, is( 1 ) );
- }
- else {
- assertThat( paramCount, is( 2 ) );
+ {
+ // Multiload 3 items and ensure that multiload pulls 2 from the database & 1 from the cache.
+ final List entities = session.findMultiple( SimpleEntity.class, idList( 3 ),
+ CacheMode.NORMAL,
+ SessionChecking.ENABLED
+ );
+ assertEquals( 3, entities.size() );
+ assertEquals( 1, statistics.getSecondLevelCacheHitCount() );
+
+ for ( SimpleEntity entity : entities ) {
+ assertTrue( session.contains( entity ) );
+ }
+
+ final int paramCount = StringHelper.countUnquoted(
+ statementInspector.getSqlQueries().get( 0 ),
+ '?'
+ );
+
+ final Dialect dialect = session.getSessionFactory().getJdbcServices().getDialect();
+ if ( MultiKeyLoadHelper.supportsSqlArrayType( dialect ) ) {
+ assertThat( paramCount, is( 1 ) );
+ }
+ else {
+ assertThat( paramCount, is( 2 ) );
+ }
}
}
);
@@ -392,31 +464,60 @@ public void testUnorderedMultiLoadFrom2ndLevelCache(SessionFactoryScope scope) {
// Validate that the entity is still in the Level 2 cache
assertTrue( session.getSessionFactory().getCache().containsEntity( SimpleEntity.class, 2 ) );
- statementInspector.getSqlQueries().clear();
-
- // Multiload 3 items and ensure that multiload pulls 2 from the database & 1 from the cache.
- List entities = session.byMultipleIds( SimpleEntity.class )
- .with( CacheMode.NORMAL )
- .enableSessionCheck( true )
- .enableOrderedReturn( false )
- .multiLoad( ids( 3 ) );
- assertEquals( 3, entities.size() );
- assertEquals( 1, statistics.getSecondLevelCacheHitCount() );
+ statementInspector.clear();
- for ( SimpleEntity entity : entities ) {
- assertTrue( session.contains( entity ) );
+ {
+ // Multiload 3 items and ensure that multiload pulls 2 from the database & 1 from the cache.
+ final List entities = session.byMultipleIds( SimpleEntity.class )
+ .with( CacheMode.NORMAL )
+ .enableSessionCheck( true )
+ .enableOrderedReturn( false )
+ .multiLoad( ids( 3 ) );
+ assertEquals( 3, entities.size() );
+ assertEquals( 1, statistics.getSecondLevelCacheHitCount() );
+
+ for ( SimpleEntity entity : entities ) {
+ assertTrue( session.contains( entity ) );
+ }
+ final int paramCount = StringHelper.countUnquoted(
+ statementInspector.getSqlQueries().get( 0 ),
+ '?'
+ );
+
+ final Dialect dialect = session.getSessionFactory().getJdbcServices().getDialect();
+ if ( MultiKeyLoadHelper.supportsSqlArrayType( dialect ) ) {
+ assertThat( paramCount, is( 1 ) );
+ }
+ else {
+ assertThat( paramCount, is( 2 ) );
+ }
}
- final int paramCount = StringHelper.countUnquoted(
- statementInspector.getSqlQueries().get( 0 ),
- '?'
- );
- final Dialect dialect = session.getSessionFactory().getJdbcServices().getDialect();
- if ( MultiKeyLoadHelper.supportsSqlArrayType( dialect ) ) {
- assertThat( paramCount, is( 1 ) );
- }
- else {
- assertThat( paramCount, is( 2 ) );
+ {
+ // Multiload 3 items and ensure that multiload pulls 2 from the database & 1 from the cache.
+ final List entities = session.findMultiple( SimpleEntity.class, idList( 3 ),
+ CacheMode.NORMAL,
+ SessionChecking.ENABLED,
+ OrderedReturn.UNORDERED
+ );
+ assertEquals( 3, entities.size() );
+ assertEquals( 1, statistics.getSecondLevelCacheHitCount() );
+
+ for ( SimpleEntity entity : entities ) {
+ assertTrue( session.contains( entity ) );
+ }
+ final int paramCount = StringHelper.countUnquoted(
+ statementInspector.getSqlQueries().get( 0 ),
+ '?'
+ );
+
+ final Dialect dialect = session.getSessionFactory().getJdbcServices().getDialect();
+ if ( MultiKeyLoadHelper.supportsSqlArrayType( dialect ) ) {
+ assertThat( paramCount, is( 1 ) );
+ }
+ else {
+ assertThat( paramCount, is( 2 ) );
+ }
}
}
);
@@ -434,27 +535,54 @@ public void testOrderedMultiLoadFrom2ndLevelCachePendingDelete(SessionFactorySco
statementInspector.clear();
- // Multi-load 3 items and ensure that it pulls 2 from the database & 1 from the cache.
- List entities = session.byMultipleIds( SimpleEntity.class )
- .with( CacheMode.NORMAL )
- .enableSessionCheck( true )
- .enableOrderedReturn( true )
- .multiLoad( ids( 3 ) );
- assertEquals( 3, entities.size() );
-
- assertNull( entities.get( 1 ) );
-
- final int paramCount = StringHelper.countUnquoted(
- statementInspector.getSqlQueries().get( 0 ),
- '?'
- );
-
- final Dialect dialect = session.getSessionFactory().getJdbcServices().getDialect();
- if ( MultiKeyLoadHelper.supportsSqlArrayType( dialect ) ) {
- assertThat( paramCount, is( 1 ) );
+ {
+ // Multi-load 3 items and ensure that it pulls 2 from the database & 1 from the cache.
+ final List entities = session.byMultipleIds( SimpleEntity.class )
+ .with( CacheMode.NORMAL )
+ .enableSessionCheck( true )
+ .enableOrderedReturn( true )
+ .multiLoad( ids( 3 ) );
+ assertEquals( 3, entities.size() );
+
+ assertNull( entities.get( 1 ) );
+
+ final int paramCount = StringHelper.countUnquoted(
+ statementInspector.getSqlQueries().get( 0 ),
+ '?'
+ );
+
+ final Dialect dialect = session.getSessionFactory().getJdbcServices().getDialect();
+ if ( MultiKeyLoadHelper.supportsSqlArrayType( dialect ) ) {
+ assertThat( paramCount, is( 1 ) );
+ }
+ else {
+ assertThat( paramCount, is( 2 ) );
+ }
}
- else {
- assertThat( paramCount, is( 2 ) );
+
+ {
+ // Multi-load 3 items and ensure that it pulls 2 from the database & 1 from the cache.
+ final List entities = session.findMultiple( SimpleEntity.class, idList( 3 ),
+ CacheMode.NORMAL,
+ SessionChecking.ENABLED,
+ OrderedReturn.ORDERED
+ );
+ assertEquals( 3, entities.size() );
+
+ assertNull( entities.get( 1 ) );
+
+ final int paramCount = StringHelper.countUnquoted(
+ statementInspector.getSqlQueries().get( 0 ),
+ '?'
+ );
+
+ final Dialect dialect = session.getSessionFactory().getJdbcServices().getDialect();
+ if ( MultiKeyLoadHelper.supportsSqlArrayType( dialect ) ) {
+ assertThat( paramCount, is( 1 ) );
+ }
+ else {
+ assertThat( paramCount, is( 2 ) );
+ }
}
}
);
@@ -472,33 +600,66 @@ public void testOrderedMultiLoadFrom2ndLevelCachePendingDeleteReturnRemoved(Sess
statementInspector.clear();
- // Multiload 3 items and ensure that multiload pulls 2 from the database & 1 from the cache.
- List entities = session.byMultipleIds( SimpleEntity.class )
- .with( CacheMode.NORMAL )
- .enableSessionCheck( true )
- .enableOrderedReturn( true )
- .enableReturnOfDeletedEntities( true )
- .multiLoad( ids( 3 ) );
- assertEquals( 3, entities.size() );
-
- SimpleEntity deletedEntity = entities.get( 1 );
- assertNotNull( deletedEntity );
-
- final EntityEntry entry = session.getPersistenceContext()
- .getEntry( deletedEntity );
- assertTrue( entry.getStatus().isDeletedOrGone() );
-
- final int paramCount = StringHelper.countUnquoted(
- statementInspector.getSqlQueries().get( 0 ),
- '?'
- );
-
- final Dialect dialect = session.getSessionFactory().getJdbcServices().getDialect();
- if ( MultiKeyLoadHelper.supportsSqlArrayType( dialect ) ) {
- assertThat( paramCount, is( 1 ) );
+ {
+ // Multiload 3 items and ensure that multiload pulls 2 from the database & 1 from the cache.
+ final List entities = session.byMultipleIds( SimpleEntity.class )
+ .with( CacheMode.NORMAL )
+ .enableSessionCheck( true )
+ .enableOrderedReturn( true )
+ .enableReturnOfDeletedEntities( true )
+ .multiLoad( ids( 3 ) );
+ assertEquals( 3, entities.size() );
+
+ SimpleEntity deletedEntity = entities.get( 1 );
+ assertNotNull( deletedEntity );
+
+ EntityEntry entry = session.getPersistenceContext()
+ .getEntry( deletedEntity );
+ assertTrue( entry.getStatus().isDeletedOrGone() );
+
+ final int paramCount = StringHelper.countUnquoted(
+ statementInspector.getSqlQueries().get( 0 ),
+ '?'
+ );
+
+ final Dialect dialect = session.getSessionFactory().getJdbcServices().getDialect();
+ if ( MultiKeyLoadHelper.supportsSqlArrayType( dialect ) ) {
+ assertThat( paramCount, is( 1 ) );
+ }
+ else {
+ assertThat( paramCount, is( 2 ) );
+ }
}
- else {
- assertThat( paramCount, is( 2 ) );
+
+ {
+ // Multiload 3 items and ensure that multiload pulls 2 from the database & 1 from the cache.
+ final List entities = session.findMultiple( SimpleEntity.class, idList( 3 ),
+ CacheMode.NORMAL,
+ SessionChecking.ENABLED,
+ OrderedReturn.ORDERED,
+ IncludeRemovals.INCLUDE
+ );
+ assertEquals( 3, entities.size() );
+
+ SimpleEntity deletedEntity = entities.get( 1 );
+ assertNotNull( deletedEntity );
+
+ EntityEntry entry = session.getPersistenceContext()
+ .getEntry( deletedEntity );
+ assertTrue( entry.getStatus().isDeletedOrGone() );
+
+ final int paramCount = StringHelper.countUnquoted(
+ statementInspector.getSqlQueries().get( 0 ),
+ '?'
+ );
+
+ final Dialect dialect = session.getSessionFactory().getJdbcServices().getDialect();
+ if ( MultiKeyLoadHelper.supportsSqlArrayType( dialect ) ) {
+ assertThat( paramCount, is( 1 ) );
+ }
+ else {
+ assertThat( paramCount, is( 2 ) );
+ }
}
} );
}
@@ -515,27 +676,54 @@ public void testUnorderedMultiLoadFrom2ndLevelCachePendingDelete(SessionFactoryS
statementInspector.clear();
- // Multiload 3 items and ensure that multiload pulls 2 from the database & 1 from the cache.
- List entities = session.byMultipleIds( SimpleEntity.class )
- .with( CacheMode.NORMAL )
- .enableSessionCheck( true )
- .enableOrderedReturn( false )
- .multiLoad( ids( 3 ) );
- assertEquals( 3, entities.size() );
-
- assertTrue( entities.stream().anyMatch( Objects::isNull ) );
-
- final int paramCount = StringHelper.countUnquoted(
- statementInspector.getSqlQueries().get( 0 ),
- '?'
- );
-
- final Dialect dialect = session.getSessionFactory().getJdbcServices().getDialect();
- if ( MultiKeyLoadHelper.supportsSqlArrayType( dialect ) ) {
- assertThat( paramCount, is( 1 ) );
+ {
+ // Multiload 3 items and ensure that multiload pulls 2 from the database & 1 from the cache.
+ final List entities = session.byMultipleIds( SimpleEntity.class )
+ .with( CacheMode.NORMAL )
+ .enableSessionCheck( true )
+ .enableOrderedReturn( false )
+ .multiLoad( ids( 3 ) );
+ assertEquals( 3, entities.size() );
+
+ assertTrue( entities.stream().anyMatch( Objects::isNull ) );
+
+ final int paramCount = StringHelper.countUnquoted(
+ statementInspector.getSqlQueries().get( 0 ),
+ '?'
+ );
+
+ final Dialect dialect = session.getSessionFactory().getJdbcServices().getDialect();
+ if ( MultiKeyLoadHelper.supportsSqlArrayType( dialect ) ) {
+ assertThat( paramCount, is( 1 ) );
+ }
+ else {
+ assertThat( paramCount, is( 2 ) );
+ }
}
- else {
- assertThat( paramCount, is( 2 ) );
+
+ {
+ // Multiload 3 items and ensure that multiload pulls 2 from the database & 1 from the cache.
+ final List entities = session.findMultiple( SimpleEntity.class, idList( 3 ),
+ CacheMode.NORMAL,
+ SessionChecking.ENABLED,
+ OrderedReturn.UNORDERED
+ );
+ assertEquals( 3, entities.size() );
+
+ assertTrue( entities.stream().anyMatch( Objects::isNull ) );
+
+ final int paramCount = StringHelper.countUnquoted(
+ statementInspector.getSqlQueries().get( 0 ),
+ '?'
+ );
+
+ final Dialect dialect = session.getSessionFactory().getJdbcServices().getDialect();
+ if ( MultiKeyLoadHelper.supportsSqlArrayType( dialect ) ) {
+ assertThat( paramCount, is( 1 ) );
+ }
+ else {
+ assertThat( paramCount, is( 2 ) );
+ }
}
} );
}
@@ -552,33 +740,66 @@ public void testUnorderedMultiLoadFrom2ndLevelCachePendingDeleteReturnRemoved(Se
statementInspector.clear();
- // Multiload 3 items and ensure that multiload pulls 2 from the database & 1 from the cache.
- List entities = session.byMultipleIds( SimpleEntity.class )
- .with( CacheMode.NORMAL )
- .enableSessionCheck( true )
- .enableOrderedReturn( false )
- .enableReturnOfDeletedEntities( true )
- .multiLoad( ids( 3 ) );
- assertEquals( 3, entities.size() );
-
- SimpleEntity deletedEntity = entities.stream().filter( simpleEntity -> simpleEntity.getId()
- .equals( 2 ) ).findAny().orElse( null );
- assertNotNull( deletedEntity );
-
- final EntityEntry entry = session.getPersistenceContext().getEntry( deletedEntity );
- assertTrue( entry.getStatus().isDeletedOrGone() );
+ {
+ // Multiload 3 items and ensure that multiload pulls 2 from the database & 1 from the cache.
+ final List entities = session.byMultipleIds( SimpleEntity.class )
+ .with( CacheMode.NORMAL )
+ .enableSessionCheck( true )
+ .enableOrderedReturn( false )
+ .enableReturnOfDeletedEntities( true )
+ .multiLoad( ids( 3 ) );
+ assertEquals( 3, entities.size() );
+
+ SimpleEntity deletedEntity = entities.stream().filter( simpleEntity -> simpleEntity.getId()
+ .equals( 2 ) ).findAny().orElse( null );
+ assertNotNull( deletedEntity );
+
+ EntityEntry entry = session.getPersistenceContext().getEntry( deletedEntity );
+ assertTrue( entry.getStatus().isDeletedOrGone() );
+
+ final int paramCount = StringHelper.countUnquoted(
+ statementInspector.getSqlQueries().get( 0 ),
+ '?'
+ );
+
+ final Dialect dialect = session.getSessionFactory().getJdbcServices().getDialect();
+ if ( MultiKeyLoadHelper.supportsSqlArrayType( dialect ) ) {
+ assertThat( paramCount, is( 1 ) );
+ }
+ else {
+ assertThat( paramCount, is( 2 ) );
+ }
+ }
- final int paramCount = StringHelper.countUnquoted(
- statementInspector.getSqlQueries().get( 0 ),
- '?'
+ {
+ // Multiload 3 items and ensure that multiload pulls 2 from the database & 1 from the cache.
+ final List entities =session.findMultiple( SimpleEntity.class, idList( 3 ),
+ CacheMode.NORMAL,
+ SessionChecking.ENABLED,
+ OrderedReturn.UNORDERED,
+ IncludeRemovals.INCLUDE
);
-
- final Dialect dialect = session.getSessionFactory().getJdbcServices().getDialect();
- if ( MultiKeyLoadHelper.supportsSqlArrayType( dialect ) ) {
- assertThat( paramCount, is( 1 ) );
- }
- else {
- assertThat( paramCount, is( 2 ) );
+ assertEquals( 3, entities.size() );
+
+ SimpleEntity deletedEntity = entities.stream().filter( simpleEntity -> simpleEntity.getId()
+ .equals( 2 ) ).findAny().orElse( null );
+ assertNotNull( deletedEntity );
+
+ EntityEntry entry = session.getPersistenceContext().getEntry( deletedEntity );
+ assertTrue( entry.getStatus().isDeletedOrGone() );
+
+ final int paramCount = StringHelper.countUnquoted(
+ statementInspector.getSqlQueries().get( 0 ),
+ '?'
+ );
+
+ final Dialect dialect = session.getSessionFactory().getJdbcServices().getDialect();
+ if ( MultiKeyLoadHelper.supportsSqlArrayType( dialect ) ) {
+ assertThat( paramCount, is( 1 ) );
+ }
+ else {
+ assertThat( paramCount, is( 2 ) );
+ }
}
} );
}
@@ -615,15 +836,24 @@ public void testMultiLoadClearsBatchFetchQueue(SessionFactoryScope scope) {
.containsEntityKey( entityKey ) );
// now bulk load, which should clean up the BatchFetchQueue entry
- List list = session.byMultipleIds( SimpleEntity.class )
- .enableSessionCheck( true )
- .multiLoad( ids( 56 ) );
-
- assertEquals( 56, list.size() );
- assertFalse( session.getPersistenceContext()
- .getBatchFetchQueue()
- .containsEntityKey( entityKey ) );
+ {
+ final List list = session.byMultipleIds( SimpleEntity.class )
+ .enableSessionCheck( true )
+ .multiLoad( ids( 56 ) );
+ assertEquals( 56, list.size() );
+ assertFalse( session.getPersistenceContext()
+ .getBatchFetchQueue()
+ .containsEntityKey( entityKey ) );
+ }
+ {
+ final List list = session.findMultiple( SimpleEntity.class, idList( 56 ),
+ SessionChecking.ENABLED );
+ assertEquals( 56, list.size() );
+ assertFalse( session.getPersistenceContext()
+ .getBatchFetchQueue()
+ .containsEntityKey( entityKey ) );
+ }
}
);
}
@@ -636,6 +866,14 @@ private Integer[] ids(int count) {
return ids;
}
+ private List idList(int count) {
+ List ids = new ArrayList<>(count);
+ for ( int i = 1; i <= count; i++ ) {
+ ids.add(i);
+ }
+ return ids;
+ }
+
@Entity( name = "SimpleEntity" )
@Table( name = "SimpleEntity" )
@Cacheable()