HHH-17620 Allow configuring filters on a stateless session

This commit is contained in:
marko-bekhta 2024-01-04 18:36:20 +01:00 committed by Christian Beikov
parent 40a2b53d30
commit 6ede95feb7
21 changed files with 578 additions and 422 deletions

View File

@ -1260,37 +1260,13 @@ public interface Session extends SharedSessionContract, EntityManager {
*/
<T> NaturalIdMultiLoadAccess<T> byMultipleNaturalId(String entityName);
/**
* Enable the named {@linkplain Filter filter} for this current session.
* <p>
* The returned {@link Filter} object must be used to bind arguments
* to parameters of the filter, and every parameter must be set before
* any other operation of this session is called.
*
* @param filterName the name of the filter to be enabled.
*
* @return the {@link Filter} instance representing the enabled filter.
*
* @throws UnknownFilterException if there is no such filter
*
* @see org.hibernate.annotations.FilterDef
*/
@Override
Filter enableFilter(String filterName);
/**
* Retrieve a currently enabled {@linkplain Filter filter} by name.
*
* @param filterName the name of the filter to be retrieved.
*
* @return the {@link Filter} instance representing the enabled filter.
*/
@Override
Filter getEnabledFilter(String filterName);
/**
* Disable the named {@linkplain Filter filter} for the current session.
*
* @param filterName the name of the filter to be disabled.
*/
@Override
void disableFilter(String filterName);
/**

View File

@ -312,6 +312,39 @@ public interface SharedSessionContract extends QueryProducer, Closeable, Seriali
*/
<T> List<EntityGraph<? super T>> getEntityGraphs(Class<T> entityClass);
/**
* Enable the named {@linkplain Filter filter} for this current session.
* <p>
* The returned {@link Filter} object must be used to bind arguments
* to parameters of the filter, and every parameter must be set before
* any other operation of this session is called.
*
* @param filterName the name of the filter to be enabled.
*
* @return the {@link Filter} instance representing the enabled filter.
*
* @throws UnknownFilterException if there is no such filter
*
* @see org.hibernate.annotations.FilterDef
*/
Filter enableFilter(String filterName);
/**
* Retrieve a currently enabled {@linkplain Filter filter} by name.
*
* @param filterName the name of the filter to be retrieved.
*
* @return the {@link Filter} instance representing the enabled filter.
*/
Filter getEnabledFilter(String filterName);
/**
* Disable the named {@linkplain Filter filter} for the current session.
*
* @param filterName the name of the filter to be disabled.
*/
void disableFilter(String filterName);
/**
* The factory which created this session.
*/

View File

@ -14,6 +14,7 @@ import jakarta.persistence.criteria.CriteriaUpdate;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.hibernate.CacheMode;
import org.hibernate.Filter;
import org.hibernate.FlushMode;
import org.hibernate.HibernateException;
import org.hibernate.Interceptor;
@ -651,4 +652,19 @@ public class SharedSessionDelegatorBaseImpl implements SharedSessionContractImpl
public <T> List<EntityGraph<? super T>> getEntityGraphs(Class<T> entityClass) {
return delegate.getEntityGraphs( entityClass );
}
@Override
public Filter enableFilter(String filterName) {
return delegate.enableFilter( filterName );
}
@Override
public Filter getEnabledFilter(String filterName) {
return delegate.getEnabledFilter( filterName );
}
@Override
public void disableFilter(String filterName) {
delegate.disableFilter( filterName );
}
}

View File

@ -21,6 +21,7 @@ import java.util.function.Function;
import jakarta.persistence.EntityGraph;
import org.hibernate.CacheMode;
import org.hibernate.EntityNameResolver;
import org.hibernate.Filter;
import org.hibernate.FlushMode;
import org.hibernate.HibernateException;
import org.hibernate.Interceptor;
@ -1491,6 +1492,28 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
return getFactory().findEntityGraphsByType( entityClass );
}
// filter support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@Override
public Filter getEnabledFilter(String filterName) {
pulseTransactionCoordinator();
return getLoadQueryInfluencers().getEnabledFilter( filterName );
}
@Override
public Filter enableFilter(String filterName) {
checkOpen();
pulseTransactionCoordinator();
return getLoadQueryInfluencers().enableFilter( filterName );
}
@Override
public void disableFilter(String filterName) {
checkOpen();
pulseTransactionCoordinator();
getLoadQueryInfluencers().disableFilter( filterName );
}
private void writeObject(ObjectOutputStream oos) throws IOException {
if ( log.isTraceEnabled() ) {
log.trace( "Serializing " + getClass().getSimpleName() + " [" );

View File

@ -1893,29 +1893,6 @@ public class SessionImpl
return loadQueryInfluencers;
}
// filter support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@Override
public Filter getEnabledFilter(String filterName) {
pulseTransactionCoordinator();
return loadQueryInfluencers.getEnabledFilter( filterName );
}
@Override
public Filter enableFilter(String filterName) {
checkOpen();
pulseTransactionCoordinator();
return loadQueryInfluencers.enableFilter( filterName );
}
@Override
public void disableFilter(String filterName) {
checkOpen();
pulseTransactionCoordinator();
loadQueryInfluencers.disableFilter( filterName );
}
// fetch profile support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@Override

View File

@ -0,0 +1,40 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.orm.test.filter;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import org.hibernate.StatelessSession;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.hibernate.testing.orm.junit.SessionFactoryScopeAware;
import org.junit.jupiter.params.provider.Arguments;
@SessionFactory
public abstract class AbstractStatefulStatelessFilterTest implements SessionFactoryScopeAware {
protected SessionFactoryScope scope;
@Override
public void injectSessionFactoryScope(SessionFactoryScope scope) {
this.scope = scope;
}
protected List<? extends Arguments> transactionKind() {
// We want to test both regular and stateless session:
BiConsumer<SessionFactoryScope, Consumer<SessionImplementor>> kind1 = SessionFactoryScope::inTransaction;
BiConsumer<SessionFactoryScope, Consumer<StatelessSession>> kind2 = SessionFactoryScope::inStatelessTransaction;
return List.of(
Arguments.of( kind1 ),
Arguments.of( kind2 )
);
}
}

View File

@ -8,6 +8,9 @@ package org.hibernate.orm.test.filter;
import java.io.Serializable;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import jakarta.persistence.Column;
import jakarta.persistence.Embeddable;
import jakarta.persistence.Embedded;
@ -19,6 +22,7 @@ import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.Root;
import jakarta.persistence.criteria.Subquery;
import org.hibernate.SharedSessionContract;
import org.hibernate.annotations.Filter;
import org.hibernate.annotations.FilterDef;
import org.hibernate.annotations.ParamDef;
@ -29,7 +33,8 @@ import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;
@ -44,12 +49,12 @@ import static org.junit.Assert.assertThat;
)
@SessionFactory
@TestForIssue(jiraKey = "HHH-10991")
public class CriteriaQueryWithAppliedFilterTest {
public class CriteriaQueryWithAppliedFilterTest extends AbstractStatefulStatelessFilterTest {
private final static Identifier STUDENT_ID = new Identifier( 2, new Identifier2( 4, 5L ) );
@BeforeEach
void setUP(SessionFactoryScope scope) {
void setUP() {
scope.inTransaction( session -> {
final Student student = new Student();
student.setId( STUDENT_ID );
@ -70,12 +75,13 @@ public class CriteriaQueryWithAppliedFilterTest {
}
@AfterEach
void tearDown(SessionFactoryScope scope) {
void tearDown() {
scope.inTransaction( session -> session.createQuery( "delete from Student" ).executeUpdate() );
}
@Test
void testSubquery(SessionFactoryScope scope) {
@ParameterizedTest
@MethodSource("transactionKind")
void testSubquery(BiConsumer<SessionFactoryScope, Consumer<? extends SharedSessionContract>> inTransaction) {
final CriteriaBuilder detachedCriteriaBuilder = scope.getSessionFactory().getCriteriaBuilder();
final CriteriaQuery<Student> criteria = detachedCriteriaBuilder.createQuery( Student.class );
criteria.from( Student.class );
@ -83,7 +89,7 @@ public class CriteriaQueryWithAppliedFilterTest {
final Root<Student> studentRoot = subquery.from( Student.class );
subquery.select( detachedCriteriaBuilder.min( studentRoot.get( "age" ) ));
scope.inTransaction( session -> {
inTransaction.accept( scope, session -> {
final CriteriaBuilder criteriaBuilder = session.getCriteriaBuilder();
final CriteriaQuery<Student> query = criteriaBuilder.createQuery( Student.class );
final Root<Student> root = query.from( Student.class );
@ -130,8 +136,9 @@ public class CriteriaQueryWithAppliedFilterTest {
});
}
@Test
void testSubqueryWithRestrictionsOnComponentTypes(SessionFactoryScope scope) {
@ParameterizedTest
@MethodSource("transactionKind")
void testSubqueryWithRestrictionsOnComponentTypes(BiConsumer<SessionFactoryScope, Consumer<? extends SharedSessionContract>> inTransaction) {
final CriteriaBuilder detachedCriteriaBuilder = scope.getSessionFactory().getCriteriaBuilder();
final CriteriaQuery<Student> criteria = detachedCriteriaBuilder.createQuery( Student.class );
criteria.from( Student.class );
@ -140,7 +147,7 @@ public class CriteriaQueryWithAppliedFilterTest {
subquery.select( detachedCriteriaBuilder.max( studentRoot.get( "age" ) ) );
subquery.where( detachedCriteriaBuilder.equal( studentRoot.get( "id" ), STUDENT_ID ) );
scope.inTransaction( session -> {
inTransaction.accept( scope, session -> {
session.enableFilter( "statusFilter" ).setParameter( "status", "active" );
// final Criteria query = session.createCriteria( Student.class );
@ -168,8 +175,9 @@ public class CriteriaQueryWithAppliedFilterTest {
});
}
@Test
void testSubqueryWithRestrictionsOnComponentTypes2(SessionFactoryScope scope) {
@ParameterizedTest
@MethodSource("transactionKind")
void testSubqueryWithRestrictionsOnComponentTypes2(BiConsumer<SessionFactoryScope, Consumer<? extends SharedSessionContract>> inTransaction) {
final CriteriaBuilder detachedCriteriaBuilder = scope.getSessionFactory().getCriteriaBuilder();
final CriteriaQuery<Student> criteria = detachedCriteriaBuilder.createQuery( Student.class );
criteria.from( Student.class );
@ -183,7 +191,7 @@ public class CriteriaQueryWithAppliedFilterTest {
)
);
scope.inTransaction( session -> {
inTransaction.accept( scope, session -> {
session.enableFilter( "statusFilter" ).setParameter( "status", "active" );
// final Criteria query = session.createCriteria( Student.class );
@ -212,9 +220,10 @@ public class CriteriaQueryWithAppliedFilterTest {
});
}
@Test
void testRestrictionsOnComponentTypes(SessionFactoryScope scope) {
scope.inTransaction( session -> {
@ParameterizedTest
@MethodSource("transactionKind")
void testRestrictionsOnComponentTypes(BiConsumer<SessionFactoryScope, Consumer<? extends SharedSessionContract>> inTransaction) {
inTransaction.accept( scope, session -> {
session.enableFilter( "statusFilter" ).setParameter( "status", "active" );
// final Criteria query = session.createCriteria( Student.class );

View File

@ -9,7 +9,10 @@ package org.hibernate.orm.test.filter;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import org.hibernate.SharedSessionContract;
import org.hibernate.annotations.Filter;
import org.hibernate.annotations.FilterDef;
import org.hibernate.annotations.FilterDefs;
@ -18,11 +21,12 @@ import org.hibernate.annotations.ParamDef;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Entity;
@ -43,12 +47,11 @@ import static org.junit.Assert.assertThat;
FilterDotNameTest.PurchaseItem.class
}
)
@SessionFactory
@TestForIssue(jiraKey = "HHH-11250")
public class FilterDotNameTest {
public class FilterDotNameTest extends AbstractStatefulStatelessFilterTest {
@BeforeEach
void setUp(SessionFactoryScope scope) {
void setUp() {
scope.inTransaction( session -> {
final PurchaseOrder order1 = new PurchaseOrder( 1L, 10L, 1000L );
final Set<PurchaseItem> items1 = new HashSet<>();
@ -67,16 +70,18 @@ public class FilterDotNameTest {
}
@AfterEach
void tearDown(SessionFactoryScope scope) {
void tearDown() {
scope.inTransaction( session -> {
session.createQuery( "DELETE FROM PurchaseItem" ).executeUpdate();
session.createQuery( "DELETE FROM PurchaseOrder" ).executeUpdate();
} );
}
@Test
void testEntityFilterNameWithoutDots(SessionFactoryScope scope) {
scope.inTransaction( session -> {
@ParameterizedTest
@MethodSource("transactionKind")
void testEntityFilterNameWithoutDots(
BiConsumer<SessionFactoryScope, Consumer<? extends SharedSessionContract>> inTransaction) {
inTransaction.accept( scope, session -> {
session.enableFilter( "customerIdFilter" ).setParameter( "customerId", 10L );
final List<PurchaseOrder> orders = session.createQuery( "FROM PurchaseOrder", PurchaseOrder.class ).getResultList();
@ -84,9 +89,11 @@ public class FilterDotNameTest {
} );
}
@Test
void testEntityFilterNameWithDots(SessionFactoryScope scope) {
scope.inTransaction( session -> {
@ParameterizedTest
@MethodSource("transactionKind")
void testEntityFilterNameWithDots(
BiConsumer<SessionFactoryScope, Consumer<? extends SharedSessionContract>> inTransaction) {
inTransaction.accept( scope, session -> {
session.enableFilter( "PurchaseOrder.customerIdFilter" ).setParameter( "customerId", 20L );
final List<PurchaseOrder> orders = session.createQuery( "FROM PurchaseOrder", PurchaseOrder.class ).getResultList();
@ -95,7 +102,7 @@ public class FilterDotNameTest {
}
@Test
void testCollectionFilterNameWithoutDots(SessionFactoryScope scope) {
void testCollectionFilterNameWithoutDots() {
scope.inTransaction( session -> {
session.enableFilter( "itemIdFilter" ).setParameter( "itemId", 100L );
@ -105,7 +112,7 @@ public class FilterDotNameTest {
}
@Test
public void testCollectionFilterNameWithDots(SessionFactoryScope scope) {
public void testCollectionFilterNameWithDots() {
scope.inTransaction( session -> {
session.enableFilter( "PurchaseOrder.itemIdFilter" ).setParameter( "itemId", 100L );

View File

@ -7,6 +7,9 @@
package org.hibernate.orm.test.filter;
import java.sql.Types;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import jakarta.persistence.Basic;
import jakarta.persistence.Column;
import jakarta.persistence.Convert;
@ -14,6 +17,7 @@ import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import org.hibernate.SharedSessionContract;
import org.hibernate.annotations.Filter;
import org.hibernate.annotations.FilterDef;
import org.hibernate.annotations.JdbcTypeCode;
@ -37,15 +41,15 @@ import org.hibernate.type.NumericBooleanConverter;
import org.hibernate.type.YesNoConverter;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.hibernate.testing.orm.junit.SkipForDialect;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
/**
* @author Steve Ebersole
@ -55,17 +59,17 @@ import static org.assertj.core.api.Assertions.fail;
FilterParameterTests.EntityTwo.class,
FilterParameterTests.EntityThree.class
} )
@SessionFactory
public class FilterParameterTests {
public class FilterParameterTests extends AbstractStatefulStatelessFilterTest {
@Test
public void testYesNo(SessionFactoryScope scope) {
@ParameterizedTest
@MethodSource("transactionKind")
public void testYesNo(BiConsumer<SessionFactoryScope, Consumer<? extends SharedSessionContract>> inTransaction) {
scope.inTransaction( (session) -> {
final EntityOne loaded = session.byId( EntityOne.class ).load( 1 );
assertThat( loaded ).isNotNull();
} );
scope.inTransaction( (session) -> {
inTransaction.accept( scope, session -> {
session.enableFilter( "filterYesNoConverter" ).setParameter( "yesNo", Boolean.FALSE );
final EntityOne loaded = session.createQuery( "from EntityOne e where e.id = :id", EntityOne.class )
@ -75,7 +79,8 @@ public class FilterParameterTests {
} );
}
@Test
@ParameterizedTest
@MethodSource("transactionKind")
@SkipForDialect(dialectClass = H2Dialect.class, reason = "H2 silently converts a boolean to string types")
@SkipForDialect(dialectClass = HSQLDialect.class, reason = "HSQL silently converts a boolean to string types")
@SkipForDialect(dialectClass = DerbyDialect.class, reason = "Derby silently converts a boolean to string types")
@ -90,35 +95,31 @@ public class FilterParameterTests {
@SkipForDialect(dialectClass = FirebirdDialect.class, reason = "Firebird silently converts a boolean to string")
@SkipForDialect(dialectClass = AltibaseDialect.class, reason = "Altibase silently converts a boolean to string")
@SkipForDialect(dialectClass = OracleDialect.class, majorVersion = 23, reason = "Oracle 23 interprets Y and T as true and N and F as false, so this works")
public void testYesNoMismatch(SessionFactoryScope scope) {
public void testYesNoMismatch(BiConsumer<SessionFactoryScope, Consumer<? extends SharedSessionContract>> inTransaction) {
scope.inTransaction( (session) -> {
final EntityOne loaded = session.byId( EntityOne.class ).load( 1 );
assertThat( loaded ).isNotNull();
} );
scope.inTransaction( (session) -> {
inTransaction.accept( scope, session -> {
session.enableFilter( "filterYesNoBoolean" ).setParameter( "yesNo", Boolean.FALSE );
try {
session.createQuery( "from EntityOne e where e.id = :id", EntityOne.class )
.setParameter( "id", 1 )
.getSingleResultOrNull();
fail( "Expecting an exception" );
}
catch (Exception expected) {
System.out.println(expected.getMessage());
}
assertThatThrownBy( () -> session.createQuery( "from EntityOne e where e.id = :id", EntityOne.class )
.setParameter( "id", 1 )
.getSingleResultOrNull() )
.isInstanceOf( Exception.class );
} );
}
@Test
public void testNumeric(SessionFactoryScope scope) {
@ParameterizedTest
@MethodSource("transactionKind")
public void testNumeric(BiConsumer<SessionFactoryScope, Consumer<? extends SharedSessionContract>> inTransaction) {
scope.inTransaction( (session) -> {
final EntityTwo loaded = session.byId( EntityTwo.class ).load( 1 );
assertThat( loaded ).isNotNull();
} );
scope.inTransaction( (session) -> {
inTransaction.accept( scope, session -> {
session.enableFilter( "filterNumberConverter" ).setParameter( "zeroOne", Boolean.FALSE );
final EntityTwo loaded = session.createQuery( "from EntityTwo e where e.id = :id", EntityTwo.class )
@ -128,7 +129,8 @@ public class FilterParameterTests {
} );
}
@Test
@ParameterizedTest
@MethodSource("transactionKind")
@SkipForDialect(dialectClass = H2Dialect.class, reason = "H2 silently converts a boolean to integral types")
@SkipForDialect(dialectClass = OracleDialect.class, reason = "Oracle silently converts a boolean to integral types")
@SkipForDialect(dialectClass = HSQLDialect.class, reason = "HSQL silently converts a boolean to integral types")
@ -142,56 +144,47 @@ public class FilterParameterTests {
@SkipForDialect(dialectClass = SybaseDialect.class, matchSubTypes = true, reason = "Sybase silently converts a boolean to integral types")
@SkipForDialect(dialectClass = AbstractHANADialect.class, matchSubTypes = true, reason = "HANA silently converts a boolean to integral types")
@SkipForDialect(dialectClass = FirebirdDialect.class, matchSubTypes = true, reason = "Firebird silently converts a boolean to integral types")
public void testNumericMismatch(SessionFactoryScope scope) {
public void testNumericMismatch(BiConsumer<SessionFactoryScope, Consumer<? extends SharedSessionContract>> inTransaction) {
scope.inTransaction( (session) -> {
final EntityTwo loaded = session.byId( EntityTwo.class ).load( 1 );
assertThat( loaded ).isNotNull();
} );
scope.inTransaction( (session) -> {
inTransaction.accept( scope, session -> {
session.enableFilter( "filterNumberBoolean" ).setParameter( "zeroOne", Boolean.FALSE );
try {
session.createQuery( "from EntityTwo e where e.id = :id", EntityTwo.class )
.setParameter( "id", 1 )
.getSingleResultOrNull();
fail( "Expecting an exception" );
}
catch (Exception expected) {
System.out.println(expected.getMessage());
}
assertThatThrownBy( () -> session.createQuery( "from EntityTwo e where e.id = :id", EntityTwo.class )
.setParameter( "id", 1 )
.getSingleResultOrNull() )
.isInstanceOf( Exception.class );
} );
}
@Test
@ParameterizedTest
@MethodSource("transactionKind")
@SkipForDialect(dialectClass = MySQLDialect.class, reason = "MySQL silently converts strings to integral types")
@SkipForDialect(dialectClass = MariaDBDialect.class, reason = "MariaDB silently converts strings to integral types")
@SkipForDialect(dialectClass = TiDBDialect.class, reason = "TiDB silently converts strings to integral types")
@SkipForDialect(dialectClass = PostgresPlusDialect.class, reason = "PostgresPlus silently converts strings to integral types")
public void testMismatch(SessionFactoryScope scope) {
public void testMismatch(BiConsumer<SessionFactoryScope, Consumer<? extends SharedSessionContract>> inTransaction) {
scope.inTransaction( (session) -> {
final EntityThree loaded = session.byId( EntityThree.class ).load( 1 );
assertThat( loaded ).isNotNull();
} );
scope.inTransaction( (session) -> {
inTransaction.accept( scope, session -> {
session.enableFilter( "filterMismatchConverter" ).setParameter( "mismatch", Boolean.FALSE );
try {
session.createQuery( "from EntityThree e where e.id = :id", EntityThree.class )
.setParameter( "id", 1 )
.getSingleResultOrNull();
fail( "Expecting an exception" );
}
catch (Exception expected) {
System.out.println(expected.getMessage());
}
assertThatThrownBy( () -> session.createQuery( "from EntityThree e where e.id = :id", EntityThree.class )
.setParameter( "id", 1 )
.getSingleResultOrNull() )
.isInstanceOf( Exception.class );
} );
}
@BeforeEach
public void prepareTestData(SessionFactoryScope scope) {
public void prepareTestData() {
scope.inTransaction( (session) -> {
session.persist( new EntityOne( 1, "one" ) );
session.persist( new EntityTwo( 1, "two" ) );
@ -200,7 +193,7 @@ public class FilterParameterTests {
}
@AfterEach
public void dropTestData(SessionFactoryScope scope) {
public void dropTestData() {
scope.inTransaction( (session) -> {
session.createMutationQuery( "delete EntityOne" ).executeUpdate();
session.createMutationQuery( "delete EntityTwo" ).executeUpdate();

View File

@ -10,6 +10,9 @@ import java.sql.Timestamp;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
@ -21,20 +24,21 @@ import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import org.hibernate.SharedSessionContract;
import org.hibernate.annotations.Filter;
import org.hibernate.annotations.FilterDef;
import org.hibernate.annotations.FilterDefs;
import org.hibernate.annotations.Filters;
import org.hibernate.annotations.ParamDef;
import org.hibernate.query.Query;
import org.hibernate.type.NumericBooleanConverter;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;
@ -49,10 +53,10 @@ import static org.junit.Assert.assertThat;
}
)
@SessionFactory
public class OneToManyWithDynamicFilterTest {
public class OneToManyWithDynamicFilterTest extends AbstractStatefulStatelessFilterTest {
@BeforeEach
void setUp(SessionFactoryScope scope) {
void setUp() {
scope.inTransaction( session -> {
final ArticleTrading articleTrading = new ArticleTrading();
articleTrading.setClassifier( "no_classification" );
@ -69,16 +73,17 @@ public class OneToManyWithDynamicFilterTest {
}
@AfterEach
void tearDown(SessionFactoryScope scope) {
void tearDown() {
scope.inTransaction( session -> {
session.createQuery( "DELETE FROM ArticleTrading" ).executeUpdate();
session.createQuery( "DELETE FROM ArticleRevision" ).executeUpdate();
} );
}
@Test
void testForIssue(SessionFactoryScope scope) {
scope.inTransaction( session -> {
@ParameterizedTest
@MethodSource("transactionKind")
void testForIssue(BiConsumer<SessionFactoryScope, Consumer<? extends SharedSessionContract>> inTransaction) {
inTransaction.accept(scope, session -> {
final org.hibernate.Filter enableFilter = session.enableFilter( "aliveOnly" );
enableFilter.setParameter( "aliveTimestamp", Timestamp.valueOf( "9999-12-31 00:00:00" ) );
enableFilter.setParameter( "deleted", true );

View File

@ -6,22 +6,27 @@
*/
package org.hibernate.orm.test.filter.hql;
import static org.junit.jupiter.api.Assertions.assertEquals;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import org.hibernate.SharedSessionContract;
import org.hibernate.annotations.Filter;
import org.hibernate.annotations.FilterDef;
import org.hibernate.annotations.ParamDef;
import org.hibernate.orm.test.filter.AbstractStatefulStatelessFilterTest;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import static org.junit.Assert.assertEquals;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
/**
* Tests for application of filters
@ -33,31 +38,33 @@ import static org.junit.Assert.assertEquals;
BasicFilteredBulkManipulationTest.Person.class
}
)
@SessionFactory
public class BasicFilteredBulkManipulationTest {
public class BasicFilteredBulkManipulationTest extends AbstractStatefulStatelessFilterTest {
@Test
void testBasicFilteredHqlDelete(SessionFactoryScope scope) {
@ParameterizedTest
@MethodSource("transactionKind")
void testBasicFilteredHqlDelete(
BiConsumer<SessionFactoryScope, Consumer<? extends SharedSessionContract>> inTransaction) {
scope.inTransaction( session -> {
session.save( new Person( "Steve", 'M' ) );
session.save( new Person( "Emmanuel", 'M' ) );
session.save( new Person( "Gail", 'F' ) );
} );
scope.inTransaction( session -> {
inTransaction.accept(scope, session -> {
session.enableFilter( "sex" ).setParameter( "sexCode", 'M' );
int count = session.createQuery( "delete Person" ).executeUpdate();
assertEquals( 2, count );
} );
}
@Test
void testBasicFilteredHqlUpdate(SessionFactoryScope scope) {
@ParameterizedTest
@MethodSource("transactionKind")
void testBasicFilteredHqlUpdate(BiConsumer<SessionFactoryScope, Consumer<? extends SharedSessionContract>> inTransaction) {
scope.inTransaction( session -> {
session.save( new Person( "Shawn", 'M' ) );
session.save( new Person( "Sally", 'F' ) );
} );
scope.inTransaction( session -> {
inTransaction.accept(scope, session -> {
session.enableFilter( "sex" ).setParameter( "sexCode", 'M' );
int count = session.createQuery( "update Person p set p.name = 'Shawn'" ).executeUpdate();
assertEquals( 1, count );
@ -65,7 +72,7 @@ public class BasicFilteredBulkManipulationTest {
}
@AfterEach
void tearDown(SessionFactoryScope scope) {
void tearDown() {
scope.inTransaction( session -> session.createQuery( "delete Person" ).executeUpdate() );
}

View File

@ -6,7 +6,12 @@
*/
package org.hibernate.orm.test.filter.hql;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.Date;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
@ -15,21 +20,20 @@ import jakarta.persistence.Inheritance;
import jakarta.persistence.InheritanceType;
import jakarta.persistence.Table;
import org.hibernate.SharedSessionContract;
import org.hibernate.annotations.Filter;
import org.hibernate.annotations.FilterDef;
import org.hibernate.annotations.ParamDef;
import org.hibernate.orm.test.filter.AbstractStatefulStatelessFilterTest;
import org.hibernate.testing.orm.junit.DialectFeatureChecks;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.RequiresDialectFeature;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
/**
* @author Steve Ebersole
@ -43,11 +47,10 @@ import static org.junit.Assert.assertThat;
JoinedFilteredBulkManipulationTest.Customer.class
}
)
@SessionFactory
public class JoinedFilteredBulkManipulationTest {
public class JoinedFilteredBulkManipulationTest extends AbstractStatefulStatelessFilterTest {
@BeforeEach
void setUp(SessionFactoryScope scope) {
void setUp() {
scope.inTransaction( session -> {
session.save( new Employee( "John", 'M', "john", new Date() ) );
session.save( new Employee( "Jane", 'F', "jane", new Date() ) );
@ -56,65 +59,71 @@ public class JoinedFilteredBulkManipulationTest {
} );
}
@Test
void testFilteredJoinedSubclassHqlDeleteRoot(SessionFactoryScope scope) {
scope.inTransaction( session -> {
@ParameterizedTest
@MethodSource("transactionKind")
void testFilteredJoinedSubclassHqlDeleteRoot(BiConsumer<SessionFactoryScope, Consumer<? extends SharedSessionContract>> inTransaction) {
inTransaction.accept( scope, session -> {
session.enableFilter( "sex" ).setParameter( "sexCode", 'M' );
final int count = session.createQuery( "delete Person" ).executeUpdate();
assertThat( count, is( 2 ) );
assertThat( count ).isEqualTo( 2 );
} );
}
@Test
void testFilteredJoinedSubclassHqlDeleteNonLeaf(SessionFactoryScope scope) {
scope.inTransaction( session -> {
@ParameterizedTest
@MethodSource("transactionKind")
void testFilteredJoinedSubclassHqlDeleteNonLeaf(BiConsumer<SessionFactoryScope, Consumer<? extends SharedSessionContract>> inTransaction) {
inTransaction.accept( scope, session -> {
session.enableFilter( "sex" ).setParameter( "sexCode", 'M' );
final int count = session.createQuery( "delete User" ).executeUpdate();
assertThat( count, is( 2 ) );
assertThat( count ).isEqualTo( 2 );
} );
}
@Test
void testFilteredJoinedSubclassHqlDeleteLeaf(SessionFactoryScope scope) {
scope.inTransaction( session -> {
@ParameterizedTest
@MethodSource("transactionKind")
void testFilteredJoinedSubclassHqlDeleteLeaf(BiConsumer<SessionFactoryScope, Consumer<? extends SharedSessionContract>> inTransaction) {
inTransaction.accept( scope, session -> {
session.enableFilter( "sex" ).setParameter( "sexCode", 'M' );
final int count = session.createQuery( "delete Employee" ).executeUpdate();
assertThat( count, is( 1 ) );
assertThat( count ).isEqualTo( 1 );
} );
}
@Test
void testFilteredJoinedSubclassHqlUpdateRoot(SessionFactoryScope scope) {
scope.inTransaction( session -> {
@ParameterizedTest
@MethodSource("transactionKind")
void testFilteredJoinedSubclassHqlUpdateRoot(BiConsumer<SessionFactoryScope, Consumer<? extends SharedSessionContract>> inTransaction) {
inTransaction.accept( scope, session -> {
session.enableFilter( "sex" ).setParameter( "sexCode", 'M' );
final int count = session.createQuery( "update Person p set p.name = '<male>'" ).executeUpdate();
assertThat( count, is( 2 ) );
assertThat( count ).isEqualTo( 2 );
} );
}
@Test
void testFilteredJoinedSubclassHqlUpdateNonLeaf(SessionFactoryScope scope) {
scope.inTransaction( session -> {
@ParameterizedTest
@MethodSource("transactionKind")
void testFilteredJoinedSubclassHqlUpdateNonLeaf(BiConsumer<SessionFactoryScope, Consumer<? extends SharedSessionContract>> inTransaction) {
inTransaction.accept( scope, session -> {
session.enableFilter( "sex" ).setParameter( "sexCode", 'M' );
final int count = session.createQuery( "update User u set u.username = :un where u.name = :n" )
.setParameter( "un", "charlie" )
.setParameter( "n", "Wanda" )
.executeUpdate();
assertThat( count, is( 0 ) );
assertThat( count ).isZero();
} );
}
@Test
void testFilteredJoinedSubclassHqlUpdateLeaf(SessionFactoryScope scope) {
scope.inTransaction( session -> {
@ParameterizedTest
@MethodSource("transactionKind")
void testFilteredJoinedSubclassHqlUpdateLeaf(BiConsumer<SessionFactoryScope, Consumer<? extends SharedSessionContract>> inTransaction) {
inTransaction.accept( scope, session -> {
session.enableFilter( "sex" ).setParameter( "sexCode", 'M' );
final int count = session.createQuery( "update Customer c set c.company = 'XYZ'" ).executeUpdate();
assertThat( count, is( 1 ) );
assertThat( count ).isEqualTo( 1 );
} );
}
@AfterEach
void tearDown(SessionFactoryScope scope) {
void tearDown() {
scope.inTransaction( session -> {
session.createQuery( "delete Person" ).executeUpdate();
} );

View File

@ -7,23 +7,32 @@
package org.hibernate.orm.test.filter.secondarytable;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import org.hibernate.Session;
import org.hibernate.SharedSessionContract;
import org.hibernate.orm.test.filter.AbstractStatefulStatelessFilterTest;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.hibernate.testing.transaction.TransactionUtil;
import org.junit.Assert;
import org.junit.Test;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
public class SecondaryTableTest extends BaseCoreFunctionalTestCase {
@DomainModel(
annotatedClasses = {
User.class
}
)
public class SecondaryTableTest extends AbstractStatefulStatelessFilterTest {
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class[] {User.class};
}
@Override
protected void prepareTest() throws Exception {
TransactionUtil.doInHibernate( this::sessionFactory, s -> {
@BeforeEach
void prepareTest() {
scope.inTransaction( s -> {
insertUser( s, "q@s.com", 21, false, "a1", "b" );
insertUser( s, "r@s.com", 22, false, "a2", "b" );
insertUser( s, "s@s.com", 23, true, "a3", "b" );
@ -31,19 +40,26 @@ public class SecondaryTableTest extends BaseCoreFunctionalTestCase {
} );
}
@Test
public void testFilter() {
try (Session session = openSession()) {
@AfterEach
void tearDown() {
scope.inTransaction( s -> {
s.createQuery( "delete from User" ).executeUpdate();
} );
}
@ParameterizedTest
@MethodSource("transactionKind")
void testFilter(BiConsumer<SessionFactoryScope, Consumer<? extends SharedSessionContract>> inTransaction) {
inTransaction.accept( scope, session -> {
/* Assert.assertEquals(
4L,
session.createQuery( "select count(u) from User u" ).uniqueResult()
);*/
session.enableFilter( "ageFilter" ).setParameter( "age", 24 );
Assert.assertEquals(
2L,
assertThat(
session.createQuery( "select count(u) from User u" ).uniqueResult()
);
}
).isEqualTo( 2L );
} );
}
private void insertUser(

View File

@ -6,34 +6,36 @@
*/
package org.hibernate.orm.test.filter.subclass.MappedSuperclass;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import org.hibernate.Transaction;
import org.junit.Test;
import org.hibernate.SharedSessionContract;
import org.hibernate.orm.test.filter.AbstractStatefulStatelessFilterTest;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import static org.hamcrest.core.Is.is;
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
import static org.junit.Assert.assertThat;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
/**
* @author Andrea Boriero
*/
@DomainModel(
annotatedClasses = {
Animal.class, Human.class, Mammal.class
}
)
public class FilterInheritanceTest extends AbstractStatefulStatelessFilterTest {
public class FilterInheritanceTest extends BaseCoreFunctionalTestCase {
private Transaction transaction;
@Override
public Class[] getAnnotatedClasses() {
return new Class[] {Animal.class, Human.class, Mammal.class};
}
@Override
@BeforeEach
protected void prepareTest() throws Exception {
doInHibernate( this::sessionFactory, session -> {
scope.inTransaction( session -> {
Mammal mammal = new Mammal();
mammal.setName( "unimportant" );
session.persist( mammal );
@ -48,22 +50,28 @@ public class FilterInheritanceTest extends BaseCoreFunctionalTestCase {
} );
}
@Override
protected boolean isCleanupTestDataRequired() {
return true;
}
@Test
@TestForIssue(jiraKey = "HHH-8895")
public void testSelectFromHuman() throws Exception {
doInHibernate( this::sessionFactory, session -> {
session.enableFilter( "nameFilter" ).setParameter( "name", "unimportant" );
List humans = session.createQuery( "SELECT h FROM Human h" ).list();
assertThat( humans.size(), is( 1 ) );
Human human = (Human) humans.get( 0 );
assertThat( human.getName(), is( "unimportant" ) );
@AfterEach
public void tearDown() throws Exception {
scope.inTransaction( session -> {
session.createQuery( "delete from Mammal" ).executeUpdate();
session.createQuery( "delete from Human" ).executeUpdate();
} );
}
@ParameterizedTest
@MethodSource("transactionKind")
@TestForIssue(jiraKey = "HHH-8895")
public void testSelectFromHuman(
BiConsumer<SessionFactoryScope, Consumer<? extends SharedSessionContract>> inTransaction) {
inTransaction.accept( scope, session -> {
session.enableFilter( "nameFilter" ).setParameter( "name", "unimportant" );
List<Human> humans = session.createQuery( "SELECT h FROM Human h", Human.class ).list();
assertThat( humans ).hasSize( 1 );
Human human = humans.get( 0 );
assertThat( human.getName() ).isEqualTo( "unimportant" );
} );
}
}

View File

@ -6,79 +6,67 @@
*/
package org.hibernate.orm.test.filter.subclass;
import junit.framework.Assert;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.junit.Test;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
public abstract class SubClassTest extends BaseCoreFunctionalTestCase{
@Override
protected void prepareTest() throws Exception {
openSession();
session.beginTransaction();
persistTestData();
session.getTransaction().commit();
session.close();
import org.hibernate.SharedSessionContract;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.orm.test.filter.AbstractStatefulStatelessFilterTest;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
public abstract class SubClassTest extends AbstractStatefulStatelessFilterTest {
@BeforeEach
void prepareTest() {
scope.inTransaction( this::persistTestData );
}
protected abstract void persistTestData();
@Override
protected abstract void persistTestData(SessionImplementor session);
@AfterEach
protected void cleanupTest() throws Exception {
openSession();
session.beginTransaction();
session.createQuery("delete from Human").executeUpdate();
session.getTransaction().commit();
session.close();
scope.inTransaction( session -> session.createQuery( "delete from Human" ).executeUpdate() );
}
@Test
public void testIqFilter(){
openSession();
session.beginTransaction();
assertCount(3);
session.enableFilter("iqRange").setParameter("min", 101).setParameter("max", 140);
assertCount(1);
session.getTransaction().commit();
session.close();
@ParameterizedTest
@MethodSource("transactionKind")
public void testIqFilter(BiConsumer<SessionFactoryScope, Consumer<? extends SharedSessionContract>> inTransaction) {
inTransaction.accept( scope, session -> {
assertCount( session, 3 );
session.enableFilter( "iqRange" ).setParameter( "min", 101 ).setParameter( "max", 140 );
assertCount( session, 1 );
} );
}
@Test
public void testPregnantFilter(){
openSession();
session.beginTransaction();
assertCount(3);
session.enableFilter("pregnantOnly");
assertCount(1);
session.getTransaction().commit();
session.close();
}
@Test
public void testNonHumanFilter(){
openSession();
session.beginTransaction();
assertCount(3);
session.enableFilter("ignoreSome").setParameter("name", "Homo Sapiens");
assertCount(0);
session.getTransaction().commit();
session.close();
}
private void assertCount(long expected){
long count = (Long) session.createQuery("select count(h) from Human h").uniqueResult();
Assert.assertEquals(expected, count);
@ParameterizedTest
@MethodSource("transactionKind")
public void testPregnantFilter(BiConsumer<SessionFactoryScope, Consumer<? extends SharedSessionContract>> inTransaction) {
inTransaction.accept( scope, session -> {
assertCount( session, 3 );
session.enableFilter( "pregnantOnly" );
assertCount( session, 1 );
} );
}
@ParameterizedTest
@MethodSource("transactionKind")
public void testNonHumanFilter(BiConsumer<SessionFactoryScope, Consumer<? extends SharedSessionContract>> inTransaction) {
inTransaction.accept( scope, session -> {
assertCount( session, 3 );
session.enableFilter( "ignoreSome" ).setParameter( "name", "Homo Sapiens" );
assertCount( session, 0 );
} );
}
private void assertCount(SharedSessionContract session, long expected) {
long count = (Long) session.createQuery( "select count(h) from Human h" ).uniqueResult();
assertEquals( expected, count );
}
}

View File

@ -6,74 +6,68 @@
*/
package org.hibernate.orm.test.filter.subclass.joined;
import junit.framework.Assert;
import static org.assertj.core.api.Assertions.assertThat;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.orm.test.filter.subclass.SubClassTest;
import org.junit.Test;
import org.hibernate.testing.orm.junit.DialectFeatureChecks;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.RequiresDialectFeature;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
@RequiresDialectFeature( feature = DialectFeatureChecks.SupportsTemporaryTable.class)
public class JoinedSubClassTest extends SubClassTest{
@RequiresDialectFeature(feature = DialectFeatureChecks.SupportsTemporaryTable.class)
@DomainModel(
annotatedClasses = {
Animal.class, Mammal.class, Human.class, Club.class
}
)
public class JoinedSubClassTest extends SubClassTest {
@Override
protected Class[] getAnnotatedClasses() {
return new Class[]{Animal.class, Mammal.class, Human.class, Club.class};
}
@Override
@AfterEach
protected void cleanupTest() throws Exception {
super.cleanupTest();
openSession();
session.beginTransaction();
session.createQuery("delete from Club").executeUpdate();
session.getTransaction().commit();
session.close();
}
scope.inTransaction( session -> {
session.createQuery( "delete from Club" ).executeUpdate();
} );
}
@Override
protected void persistTestData() {
protected void persistTestData(SessionImplementor session) {
Club club = new Club();
club.setName("Mensa applicants");
club.getMembers().add(createHuman(club, false, 90));
club.getMembers().add(createHuman(club, false, 100));
club.getMembers().add(createHuman(club, true, 110));
session.persist(club);
club.setName( "Mensa applicants" );
club.getMembers().add( createHuman( session, club, false, 90 ) );
club.getMembers().add( createHuman( session, club, false, 100 ) );
club.getMembers().add( createHuman( session, club, true, 110 ) );
session.persist( club );
}
@Test
public void testClub(){
openSession();
session.beginTransaction();
public void testClub() {
scope.inTransaction( session -> {
Club club = session.createQuery( "from Club", Club.class ).uniqueResult();
assertThat( club.getMembers() ).hasSize( 3 );
session.clear();
Club club = (Club) session.createQuery("from Club").uniqueResult();
Assert.assertEquals(3, club.getMembers().size());
session.clear();
session.enableFilter("pregnantMembers");
club = (Club) session.createQuery("from Club").uniqueResult();
Assert.assertEquals(1, club.getMembers().size());
session.clear();
session.enableFilter("iqMin").setParameter("min", 148);
club = (Club) session.createQuery("from Club").uniqueResult();
Assert.assertEquals(0, club.getMembers().size());
session.getTransaction().commit();
session.close();
session.enableFilter( "pregnantMembers" );
club = session.createQuery( "from Club", Club.class ).uniqueResult();
assertThat( club.getMembers() ).hasSize( 1 );
session.clear();
session.enableFilter( "iqMin" ).setParameter( "min", 148 );
club = session.createQuery( "from Club", Club.class ).uniqueResult();
assertThat( club.getMembers() ).isEmpty();
} );
}
private Human createHuman(Club club, boolean pregnant, int iq){
private Human createHuman(SessionImplementor session, Club club, boolean pregnant, int iq) {
Human human = new Human();
human.setClub(club);
human.setName("Homo Sapiens");
human.setPregnant(pregnant);
human.setIq(iq);
session.persist(human);
human.setClub( club );
human.setName( "Homo Sapiens" );
human.setPregnant( pregnant );
human.setIq( iq );
session.persist( human );
return human;
}
}

View File

@ -1,30 +1,67 @@
package org.hibernate.orm.test.filter.subclass.joined2;
import static org.junit.jupiter.api.Assertions.assertNull;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import org.hibernate.Session;
import org.hibernate.SharedSessionContract;
import org.hibernate.StatelessSession;
import org.hibernate.annotations.FilterDef;
import org.hibernate.annotations.ParamDef;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.junit.jupiter.api.Test;
import org.hibernate.testing.orm.junit.SessionFactoryScopeAware;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import static org.junit.jupiter.api.Assertions.assertNull;
import org.assertj.core.util.TriFunction;
@TestForIssue(jiraKey = "HHH-9646")
@SessionFactory
@DomainModel(annotatedClasses = {Animal.class, Dog.class, Owner.class, JoinedInheritanceFilterTest.class})
@DomainModel(annotatedClasses = { Animal.class, Dog.class, Owner.class, JoinedInheritanceFilterTest.class })
@FilterDef(name = "companyFilter", parameters = @ParamDef(name = "companyIdParam", type = long.class))
public class JoinedInheritanceFilterTest {
@Test public void test(SessionFactoryScope scope) {
scope.inTransaction( s -> {
s.createQuery("SELECT o FROM Owner o INNER JOIN FETCH o.dog d WHERE o.id = 1").getResultList();
s.enableFilter("companyFilter").setParameter("companyIdParam", 2l).validate();
s.createQuery("SELECT o FROM Owner o INNER JOIN FETCH o.dog d WHERE o.id = 1").getResultList();
s.createQuery("FROM Animal").getResultList();
s.createQuery("FROM Dog").getResultList();
assertNull( s.find(Owner.class, 1) );
assertNull( s.find(Animal.class, 1) );
assertNull( s.find(Dog.class, 1) );
});
public class JoinedInheritanceFilterTest implements SessionFactoryScopeAware {
private SessionFactoryScope scope;
@Override
public void injectSessionFactoryScope(SessionFactoryScope scope) {
this.scope = scope;
}
@ParameterizedTest
@MethodSource("transactionKind")
void test(BiConsumer<SessionFactoryScope, Consumer<? extends SharedSessionContract>> inTransaction,
TriFunction<SharedSessionContract, Class<?>, Object, Object> find) {
inTransaction.accept( scope, s -> {
s.createQuery( "SELECT o FROM Owner o INNER JOIN FETCH o.dog d WHERE o.id = 1" ).getResultList();
s.enableFilter( "companyFilter" ).setParameter( "companyIdParam", 2l ).validate();
s.createQuery( "SELECT o FROM Owner o INNER JOIN FETCH o.dog d WHERE o.id = 1" ).getResultList();
s.createQuery( "FROM Animal" ).getResultList();
s.createQuery( "FROM Dog" ).getResultList();
assertNull( find.apply( s, Owner.class, 1 ) );
assertNull( find.apply( s, Animal.class, 1 ) );
assertNull( find.apply( s, Dog.class, 1 ) );
} );
}
List<? extends Arguments> transactionKind() {
// We want to test both regular and stateless session:
BiConsumer<SessionFactoryScope, Consumer<SessionImplementor>> kind1 = SessionFactoryScope::inTransaction;
TriFunction<Session, Class<?>, Object, Object> find1 = Session::get;
BiConsumer<SessionFactoryScope, Consumer<StatelessSession>> kind2 = SessionFactoryScope::inStatelessTransaction;
TriFunction<StatelessSession, Class<?>, Object, Object> find2 = StatelessSession::get;
return List.of(
Arguments.of( kind1, find1 ),
Arguments.of( kind2, find2 )
);
}
}

View File

@ -7,11 +7,15 @@
package org.hibernate.orm.test.filter.subclass.singletable;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import org.hibernate.SharedSessionContract;
import org.hibernate.annotations.Filter;
import org.hibernate.annotations.FilterDef;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.dialect.H2Dialect;
import org.hibernate.orm.test.filter.AbstractStatefulStatelessFilterTest;
import org.hibernate.query.MutationQuery;
import org.hibernate.testing.orm.junit.DomainModel;
@ -24,6 +28,8 @@ import org.hibernate.testing.orm.junit.Setting;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import jakarta.persistence.DiscriminatorColumn;
import jakarta.persistence.DiscriminatorType;
@ -37,7 +43,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* @author Marco Belladelli
*/
@SessionFactory
@DomainModel(
annotatedClasses = {
SingleTableDefaultSchemaFilterTest.AbstractSuperClass.class,
@ -48,9 +53,9 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
@ServiceRegistry( settings = @Setting( name = AvailableSettings.DEFAULT_SCHEMA, value = "public" ) )
@RequiresDialect( H2Dialect.class )
@Jira( "https://hibernate.atlassian.net/browse/HHH-16661" )
public class SingleTableDefaultSchemaFilterTest {
public class SingleTableDefaultSchemaFilterTest extends AbstractStatefulStatelessFilterTest {
@BeforeEach
public void setUp(SessionFactoryScope scope) {
public void setUp() {
scope.inTransaction( session -> {
session.persist( new ChildEntityOne() );
session.persist( new ChildEntityTwo() );
@ -58,22 +63,23 @@ public class SingleTableDefaultSchemaFilterTest {
}
@AfterEach
public void cleanup(SessionFactoryScope scope) {
public void cleanup() {
scope.inTransaction(
session -> session.createMutationQuery( "delete from AbstractSuperClass" ).executeUpdate()
);
}
@Test
public void testUpdate(SessionFactoryScope scope) {
scope.inTransaction( session -> {
@ParameterizedTest
@MethodSource("transactionKind")
public void testUpdate(BiConsumer<SessionFactoryScope, Consumer<? extends SharedSessionContract>> inTransaction) {
inTransaction.accept( scope, session -> {
session.enableFilter( "dummy_filter" );
final MutationQuery updateQuery = session.createMutationQuery(
"update ChildEntityTwo cet set cet.name = 'John'" );
final int updated = updateQuery.executeUpdate();
assertEquals( 1, updated );
} );
scope.inTransaction( session -> {
inTransaction.accept( scope, session -> {
session.enableFilter( "dummy_filter" );
final List<AbstractSuperClass> resultList = session.createQuery(
"select p from AbstractSuperClass p where p.name = 'John'",
@ -83,15 +89,16 @@ public class SingleTableDefaultSchemaFilterTest {
} );
}
@Test
public void testDelete(SessionFactoryScope scope) {
scope.inTransaction( session -> {
@ParameterizedTest
@MethodSource("transactionKind")
public void testDelete(BiConsumer<SessionFactoryScope, Consumer<? extends SharedSessionContract>> inTransaction) {
inTransaction.accept( scope, session -> {
session.enableFilter( "dummy_filter" );
final MutationQuery deleteQuery = session.createMutationQuery( "delete from ChildEntityOne" );
final int deleted = deleteQuery.executeUpdate();
assertEquals( 1, deleted );
} );
scope.inTransaction( session -> {
inTransaction.accept( scope, session -> {
session.enableFilter( "dummy_filter" );
final List<AbstractSuperClass> resultList = session.createQuery(
"select p from AbstractSuperClass p",

View File

@ -14,20 +14,25 @@ import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import org.hibernate.SharedSessionContract;
import org.hibernate.annotations.Filter;
import org.hibernate.annotations.FilterDef;
import org.hibernate.orm.test.filter.AbstractStatefulStatelessFilterTest;
import org.hibernate.query.MutationQuery;
import org.hibernate.query.Query;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
/**
* @author Jan Schatteman
*/
@ -39,18 +44,19 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
SingleTableInheritanceFilterTest.ChildEntityTwo.class
}
)
@SessionFactory
public class SingleTableInheritanceFilterTest {
public class SingleTableInheritanceFilterTest extends AbstractStatefulStatelessFilterTest {
@AfterEach
public void cleanup( SessionFactoryScope scope ) {
public void cleanup() {
scope.inTransaction(
s -> s.createMutationQuery( "delete from AbstractSuperClass" ).executeUpdate()
);
}
@Test
public void testFilterAppliedOnSingleTableInheritance(SessionFactoryScope scope) {
@ParameterizedTest
@MethodSource("transactionKind")
public void testFilterAppliedOnSingleTableInheritance(
BiConsumer<SessionFactoryScope, Consumer<? extends SharedSessionContract>> inTransaction) {
scope.inTransaction(
s -> {
s.persist( new ChildEntityOne() );
@ -59,7 +65,8 @@ public class SingleTableInheritanceFilterTest {
);
// test update
scope.inTransaction(
inTransaction.accept(
scope,
s -> {
s.enableFilter( "dummy_filter" );
MutationQuery updateQuery = s.createMutationQuery( "update ChildEntityTwo cet set cet.name = 'John'");
@ -72,7 +79,8 @@ public class SingleTableInheritanceFilterTest {
);
// test delete
scope.inTransaction(
inTransaction.accept(
scope,
s -> {
s.enableFilter( "dummy_filter" );
MutationQuery deleteQuery = s.createMutationQuery( "delete from ChildEntityTwo");

View File

@ -6,32 +6,32 @@
*/
package org.hibernate.orm.test.filter.subclass.singletable;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.orm.test.filter.subclass.SubClassTest;
public class SingleTableTest extends SubClassTest{
import org.hibernate.testing.orm.junit.DomainModel;
@DomainModel(
annotatedClasses = {
Animal.class, Mammal.class, Human.class
}
)
public class SingleTableTest extends SubClassTest {
@Override
protected Class[] getAnnotatedClasses() {
return new Class[]{Animal.class, Mammal.class, Human.class};
}
@Override
protected void persistTestData() {
createHuman(false, 90);
createHuman(false, 100);
createHuman(true, 110);
protected void persistTestData(SessionImplementor session) {
createHuman( session, false, 90 );
createHuman( session, false, 100 );
createHuman( session, true, 110 );
}
private void createHuman(boolean pregnant, int iq){
private void createHuman(SessionImplementor session, boolean pregnant, int iq) {
Human human = new Human();
human.setName("Homo Sapiens");
human.setPregnant(pregnant);
human.setIq(iq);
session.persist(human);
human.setName( "Homo Sapiens" );
human.setPregnant( pregnant );
human.setIq( iq );
session.persist( human );
}
}

View File

@ -6,28 +6,31 @@
*/
package org.hibernate.orm.test.filter.subclass.tableperclass;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.orm.test.filter.subclass.SubClassTest;
public class TablePerClassTest extends SubClassTest{
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.SessionFactory;
@DomainModel(
annotatedClasses = {
Animal.class, Mammal.class, Human.class
}
)
@SessionFactory
public class TablePerClassTest extends SubClassTest {
@Override
protected Class[] getAnnotatedClasses() {
return new Class[]{Animal.class, Mammal.class, Human.class};
}
@Override
protected void persistTestData() {
createHuman(false, 90);
createHuman(false, 100);
createHuman(true, 110);
protected void persistTestData(SessionImplementor session) {
createHuman( session, false, 90 );
createHuman( session, false, 100 );
createHuman( session, true, 110 );
}
private void createHuman(boolean pregnant, int iq){
private void createHuman(SessionImplementor session, boolean pregnant, int iq) {
Human human = new Human();
human.setName("Homo Sapiens");
human.setPregnant(pregnant);
human.setIq(iq);
session.persist(human);
human.setName( "Homo Sapiens" );
human.setPregnant( pregnant );
human.setIq( iq );
session.persist( human );
}
}