Various fixes from Search integration testing
- do not cache Criteria query plans (added Trello card to revisit) - support for StatelessSession in JUnit 5 extensions (SessionFactoryScope)
This commit is contained in:
parent
23f64fc675
commit
4402843d1c
|
@ -17,6 +17,7 @@ import org.hibernate.jdbc.ReturningWork;
|
||||||
import org.hibernate.jdbc.Work;
|
import org.hibernate.jdbc.Work;
|
||||||
import org.hibernate.procedure.ProcedureCall;
|
import org.hibernate.procedure.ProcedureCall;
|
||||||
import org.hibernate.query.QueryProducer;
|
import org.hibernate.query.QueryProducer;
|
||||||
|
import org.hibernate.query.criteria.HibernateCriteriaBuilder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contract methods shared between {@link Session} and {@link StatelessSession}.
|
* Contract methods shared between {@link Session} and {@link StatelessSession}.
|
||||||
|
@ -153,7 +154,7 @@ public interface SharedSessionContract extends QueryProducer, Serializable {
|
||||||
* @return an instance of CriteriaBuilder
|
* @return an instance of CriteriaBuilder
|
||||||
* @throws IllegalStateException if the StatelessSession has been closed
|
* @throws IllegalStateException if the StatelessSession has been closed
|
||||||
*/
|
*/
|
||||||
CriteriaBuilder getCriteriaBuilder();
|
HibernateCriteriaBuilder getCriteriaBuilder();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
<T> org.hibernate.query.Query<T> createQuery(String queryString, Class<T> resultType);
|
<T> org.hibernate.query.Query<T> createQuery(String queryString, Class<T> resultType);
|
||||||
|
|
|
@ -18,7 +18,6 @@ import javax.persistence.EntityManagerFactory;
|
||||||
import javax.persistence.FlushModeType;
|
import javax.persistence.FlushModeType;
|
||||||
import javax.persistence.LockModeType;
|
import javax.persistence.LockModeType;
|
||||||
import javax.persistence.StoredProcedureQuery;
|
import javax.persistence.StoredProcedureQuery;
|
||||||
import javax.persistence.criteria.CriteriaBuilder;
|
|
||||||
import javax.persistence.criteria.CriteriaDelete;
|
import javax.persistence.criteria.CriteriaDelete;
|
||||||
import javax.persistence.criteria.CriteriaQuery;
|
import javax.persistence.criteria.CriteriaQuery;
|
||||||
import javax.persistence.criteria.CriteriaUpdate;
|
import javax.persistence.criteria.CriteriaUpdate;
|
||||||
|
@ -54,6 +53,7 @@ import org.hibernate.jdbc.ReturningWork;
|
||||||
import org.hibernate.jdbc.Work;
|
import org.hibernate.jdbc.Work;
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
import org.hibernate.procedure.ProcedureCall;
|
import org.hibernate.procedure.ProcedureCall;
|
||||||
|
import org.hibernate.query.criteria.HibernateCriteriaBuilder;
|
||||||
import org.hibernate.query.spi.QueryImplementor;
|
import org.hibernate.query.spi.QueryImplementor;
|
||||||
import org.hibernate.query.spi.ScrollableResultsImplementor;
|
import org.hibernate.query.spi.ScrollableResultsImplementor;
|
||||||
import org.hibernate.query.sql.spi.NativeQueryImplementor;
|
import org.hibernate.query.sql.spi.NativeQueryImplementor;
|
||||||
|
@ -432,7 +432,7 @@ public class SessionDelegatorBaseImpl implements SessionImplementor {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CriteriaBuilder getCriteriaBuilder() {
|
public HibernateCriteriaBuilder getCriteriaBuilder() {
|
||||||
return delegate.getCriteriaBuilder();
|
return delegate.getCriteriaBuilder();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,6 @@ import java.util.TimeZone;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import javax.persistence.FlushModeType;
|
import javax.persistence.FlushModeType;
|
||||||
import javax.persistence.TransactionRequiredException;
|
import javax.persistence.TransactionRequiredException;
|
||||||
import javax.persistence.criteria.CriteriaBuilder;
|
|
||||||
import javax.persistence.criteria.CriteriaDelete;
|
import javax.persistence.criteria.CriteriaDelete;
|
||||||
import javax.persistence.criteria.CriteriaQuery;
|
import javax.persistence.criteria.CriteriaQuery;
|
||||||
import javax.persistence.criteria.CriteriaUpdate;
|
import javax.persistence.criteria.CriteriaUpdate;
|
||||||
|
@ -61,6 +60,7 @@ import org.hibernate.procedure.ProcedureCall;
|
||||||
import org.hibernate.procedure.internal.ProcedureCallImpl;
|
import org.hibernate.procedure.internal.ProcedureCallImpl;
|
||||||
import org.hibernate.procedure.spi.NamedCallableQueryMemento;
|
import org.hibernate.procedure.spi.NamedCallableQueryMemento;
|
||||||
import org.hibernate.query.Query;
|
import org.hibernate.query.Query;
|
||||||
|
import org.hibernate.query.criteria.HibernateCriteriaBuilder;
|
||||||
import org.hibernate.query.hql.spi.HqlQueryImplementor;
|
import org.hibernate.query.hql.spi.HqlQueryImplementor;
|
||||||
import org.hibernate.query.hql.spi.NamedHqlQueryMemento;
|
import org.hibernate.query.hql.spi.NamedHqlQueryMemento;
|
||||||
import org.hibernate.query.named.NamedResultSetMappingMemento;
|
import org.hibernate.query.named.NamedResultSetMappingMemento;
|
||||||
|
@ -908,7 +908,7 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CriteriaBuilder getCriteriaBuilder() {
|
public HibernateCriteriaBuilder getCriteriaBuilder() {
|
||||||
checkOpen();
|
checkOpen();
|
||||||
return getFactory().getCriteriaBuilder();
|
return getFactory().getCriteriaBuilder();
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,6 +72,11 @@ public class QuerySqmImpl<R>
|
||||||
extends AbstractQuery<R>
|
extends AbstractQuery<R>
|
||||||
implements HqlQueryImplementor<R>, ExecutionContext {
|
implements HqlQueryImplementor<R>, ExecutionContext {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The value used for {@link #getQueryString} for Criteria-based queries
|
||||||
|
*/
|
||||||
|
public static final String CRITERIA_HQL_STRING = "<criteria>";
|
||||||
|
|
||||||
private final String hqlString;
|
private final String hqlString;
|
||||||
private final SqmStatement sqmStatement;
|
private final SqmStatement sqmStatement;
|
||||||
private final Class resultType;
|
private final Class resultType;
|
||||||
|
@ -212,7 +217,7 @@ public class QuerySqmImpl<R>
|
||||||
throw new IllegalArgumentException( "Non-select queries cannot be typed" );
|
throw new IllegalArgumentException( "Non-select queries cannot be typed" );
|
||||||
}
|
}
|
||||||
|
|
||||||
this.hqlString = "<criteria>";
|
this.hqlString = CRITERIA_HQL_STRING;
|
||||||
this.sqmStatement = sqmStatement;
|
this.sqmStatement = sqmStatement;
|
||||||
this.resultType = resultType;
|
this.resultType = resultType;
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ import org.hibernate.query.spi.QueryInterpretationCache;
|
||||||
public class SqmInterpretationsKey implements QueryInterpretationCache.Key {
|
public class SqmInterpretationsKey implements QueryInterpretationCache.Key {
|
||||||
@SuppressWarnings("WeakerAccess")
|
@SuppressWarnings("WeakerAccess")
|
||||||
public static SqmInterpretationsKey generateFrom(QuerySqmImpl query) {
|
public static SqmInterpretationsKey generateFrom(QuerySqmImpl query) {
|
||||||
if ( !isCacheable( query ) ) {
|
if ( ! isCacheable( query ) ) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,6 +45,13 @@ public class SqmInterpretationsKey implements QueryInterpretationCache.Key {
|
||||||
private static boolean isCacheable(QuerySqmImpl<?> query) {
|
private static boolean isCacheable(QuerySqmImpl<?> query) {
|
||||||
assert query.getQueryOptions().getAppliedGraph() != null;
|
assert query.getQueryOptions().getAppliedGraph() != null;
|
||||||
|
|
||||||
|
if ( QuerySqmImpl.CRITERIA_HQL_STRING.equals( query.getQueryString() ) ) {
|
||||||
|
// for now at least, skip caching Criteria-based plans
|
||||||
|
// - especially wrt parameters atm; this works with HQL because the parameters
|
||||||
|
// are part of the query string; with Criteria, they are not.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if ( query.getSession().getLoadQueryInfluencers().hasEnabledFilters() ) {
|
if ( query.getSession().getLoadQueryInfluencers().hasEnabledFilters() ) {
|
||||||
// At the moment we cannot cache query plan if there is filter enabled.
|
// At the moment we cannot cache query plan if there is filter enabled.
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -25,12 +25,13 @@ import org.hibernate.metamodel.model.domain.MapPersistentAttribute;
|
||||||
import org.hibernate.metamodel.model.domain.PluralPersistentAttribute;
|
import org.hibernate.metamodel.model.domain.PluralPersistentAttribute;
|
||||||
import org.hibernate.metamodel.model.domain.SingularPersistentAttribute;
|
import org.hibernate.metamodel.model.domain.SingularPersistentAttribute;
|
||||||
import org.hibernate.query.NavigablePath;
|
import org.hibernate.query.NavigablePath;
|
||||||
|
import org.hibernate.query.hql.spi.SqmCreationState;
|
||||||
import org.hibernate.query.sqm.IllegalPathUsageException;
|
import org.hibernate.query.sqm.IllegalPathUsageException;
|
||||||
import org.hibernate.query.sqm.NodeBuilder;
|
import org.hibernate.query.sqm.NodeBuilder;
|
||||||
import org.hibernate.query.sqm.SqmPathSource;
|
import org.hibernate.query.sqm.SqmPathSource;
|
||||||
import org.hibernate.query.hql.spi.SqmCreationState;
|
|
||||||
import org.hibernate.query.sqm.tree.expression.AbstractSqmExpression;
|
import org.hibernate.query.sqm.tree.expression.AbstractSqmExpression;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmExpression;
|
import org.hibernate.query.sqm.tree.expression.SqmExpression;
|
||||||
|
import org.hibernate.type.BasicType;
|
||||||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -217,24 +218,32 @@ public abstract class AbstractSqmPath<T> extends AbstractSqmExpression<T> implem
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public SqmPath get(String attributeName) {
|
public SqmPath<?> get(String attributeName) {
|
||||||
|
|
||||||
// todo (6.0) : this is similar to the idea of creating an SqmExpression for a Navigable
|
// todo (6.0) : this is similar to the idea of creating an SqmExpression for a Navigable
|
||||||
// should make these stylistically consistent, either -
|
// should make these stylistically consistent, either -
|
||||||
// 1) add `Navigable#createCriteriaExpression` (ala, the exist `#createSqmExpression`)
|
// 1) add `Navigable#createCriteriaExpression` (ala, the exist `#createSqmExpression`)
|
||||||
// 2) remove `Navigable#createSqmExpression` and use the approach used here instead.
|
// 2) remove `Navigable#createSqmExpression` and use the approach used here instead.
|
||||||
|
|
||||||
|
if ( getReferencedPathSource().getSqmPathType() instanceof BasicType ) {
|
||||||
|
throw new IllegalStateException( "Cannot resolve path `" + attributeName + "` relative to a basic-valued path: `" + getNavigablePath() + "`" );
|
||||||
|
}
|
||||||
|
|
||||||
return resolvePath(
|
return resolvePath(
|
||||||
attributeName,
|
attributeName,
|
||||||
(pathSource, name) -> {
|
(pathSource, name) -> {
|
||||||
final SqmPathSource subNavigable = getReferencedPathSource().findSubPathSource( attributeName );
|
final SqmPathSource<?> subNavigable = getReferencedPathSource().findSubPathSource( attributeName );
|
||||||
|
|
||||||
|
if ( subNavigable == null ) {
|
||||||
|
throw new IllegalArgumentException( "Could not resolve attribute named `" + attributeName + "` relative to `" + getNavigablePath() + "`" );
|
||||||
|
}
|
||||||
|
|
||||||
if ( subNavigable instanceof SingularPersistentAttribute ) {
|
if ( subNavigable instanceof SingularPersistentAttribute ) {
|
||||||
return createSingularPath( (SingularPersistentAttribute) subNavigable );
|
return createSingularPath( (SingularPersistentAttribute<?,?>) subNavigable );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
assert subNavigable instanceof PluralPersistentAttribute;
|
assert subNavigable instanceof PluralPersistentAttribute;
|
||||||
return createPluralPath( (PluralPersistentAttribute) subNavigable );
|
return createPluralPath( (PluralPersistentAttribute<?,?,?>) subNavigable );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
|
@ -6,175 +6,153 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.orm.test.query.criteria;
|
package org.hibernate.orm.test.query.criteria;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import javax.persistence.Entity;
|
|
||||||
import javax.persistence.GeneratedValue;
|
|
||||||
import javax.persistence.Id;
|
|
||||||
import javax.persistence.criteria.CriteriaBuilder;
|
|
||||||
import javax.persistence.criteria.CriteriaQuery;
|
import javax.persistence.criteria.CriteriaQuery;
|
||||||
import javax.persistence.criteria.ParameterExpression;
|
import javax.persistence.criteria.ParameterExpression;
|
||||||
import javax.persistence.criteria.Root;
|
import javax.persistence.criteria.Root;
|
||||||
|
|
||||||
import org.hibernate.IrrelevantEntity;
|
|
||||||
import org.hibernate.query.criteria.HibernateCriteriaBuilder;
|
import org.hibernate.query.criteria.HibernateCriteriaBuilder;
|
||||||
import org.hibernate.query.criteria.JpaCriteriaQuery;
|
import org.hibernate.query.criteria.JpaCriteriaQuery;
|
||||||
import org.hibernate.query.criteria.JpaRoot;
|
import org.hibernate.query.criteria.JpaRoot;
|
||||||
import org.hibernate.query.spi.QueryParameterImplementor;
|
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmParameter;
|
|
||||||
import org.hibernate.sql.ast.tree.expression.JdbcParameter;
|
|
||||||
|
|
||||||
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
|
import org.hibernate.testing.orm.domain.gambit.BasicEntity;
|
||||||
import org.junit.Test;
|
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;
|
||||||
|
|
||||||
/**
|
@DomainModel( annotatedClasses = BasicEntity.class )
|
||||||
* @author Steve Ebersole
|
@SessionFactory
|
||||||
*/
|
public class BasicCriteriaExecutionTests {
|
||||||
public class BasicCriteriaExecutionTests extends BaseNonConfigCoreFunctionalTestCase {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Class[] getAnnotatedClasses() {
|
|
||||||
return new Class[] { BasicEntity.class };
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testExecutingBasicCriteriaQuery() {
|
public void testExecutingBasicCriteriaQuery(SessionFactoryScope scope) {
|
||||||
final CriteriaBuilder criteriaBuilder = sessionFactory().getCriteriaBuilder();
|
scope.inTransaction(
|
||||||
|
|
||||||
final CriteriaQuery<Object> criteria = criteriaBuilder.createQuery();
|
|
||||||
|
|
||||||
final Root<BasicEntity> root = criteria.from( BasicEntity.class );
|
|
||||||
|
|
||||||
criteria.select( root );
|
|
||||||
|
|
||||||
inSession(
|
|
||||||
session -> session.createQuery( criteria ).list()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testIt() {
|
|
||||||
inSession(
|
|
||||||
session -> {
|
session -> {
|
||||||
CriteriaBuilder criteriaBuilder = session.getCriteriaBuilder();
|
final HibernateCriteriaBuilder criteriaBuilder = session.getCriteriaBuilder();
|
||||||
CriteriaQuery<BasicEntity> criteria = criteriaBuilder.createQuery( BasicEntity.class );
|
|
||||||
criteria.from( BasicEntity.class );
|
final CriteriaQuery<Object> criteria = criteriaBuilder.createQuery();
|
||||||
List<BasicEntity> results = session.createQuery( criteria ).list();
|
final Root<BasicEntity> root = criteria.from( BasicEntity.class );
|
||||||
|
criteria.select( root );
|
||||||
|
|
||||||
|
session.createQuery( criteria ).list();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testExecutingBasicCriteriaQueryInStatelessSession() {
|
public void testIt(SessionFactoryScope scope) {
|
||||||
final CriteriaBuilder criteriaBuilder = sessionFactory().getCriteriaBuilder();
|
scope.inTransaction(
|
||||||
|
session -> {
|
||||||
final CriteriaQuery<Object> criteria = criteriaBuilder.createQuery();
|
final HibernateCriteriaBuilder criteriaBuilder = session.getCriteriaBuilder();
|
||||||
|
CriteriaQuery<BasicEntity> criteria = criteriaBuilder.createQuery( BasicEntity.class );
|
||||||
final Root<BasicEntity> root = criteria.from( BasicEntity.class );
|
criteria.from( BasicEntity.class );
|
||||||
|
session.createQuery( criteria ).list();
|
||||||
criteria.select( root );
|
}
|
||||||
|
|
||||||
inStatelessSession(
|
|
||||||
session -> session.createQuery( criteria ).list()
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testExecutingBasicCriteriaQueryLiteralPredicate() {
|
public void testExecutingBasicCriteriaQueryInStatelessSession(SessionFactoryScope scope) {
|
||||||
final CriteriaBuilder criteriaBuilder = sessionFactory().getCriteriaBuilder();
|
scope.inTransaction(
|
||||||
|
session -> {
|
||||||
|
final HibernateCriteriaBuilder criteriaBuilder = session.getCriteriaBuilder();
|
||||||
|
|
||||||
final CriteriaQuery<Object> criteria = criteriaBuilder.createQuery();
|
final CriteriaQuery<Object> criteria = criteriaBuilder.createQuery();
|
||||||
|
final Root<BasicEntity> root = criteria.from( BasicEntity.class );
|
||||||
|
criteria.select( root );
|
||||||
|
|
||||||
final Root<BasicEntity> root = criteria.from( BasicEntity.class );
|
session.createQuery( criteria ).list();
|
||||||
|
}
|
||||||
criteria.select( root );
|
|
||||||
|
|
||||||
criteria.where( criteriaBuilder.equal( criteriaBuilder.literal( 1 ), criteriaBuilder.literal( 1 ) ) );
|
|
||||||
|
|
||||||
inSession(
|
|
||||||
session -> session.createQuery( criteria ).list()
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testExecutingBasicCriteriaQueryLiteralPredicateInStatelessSession() {
|
public void testExecutingBasicCriteriaQueryLiteralPredicate(SessionFactoryScope scope) {
|
||||||
final CriteriaBuilder criteriaBuilder = sessionFactory().getCriteriaBuilder();
|
scope.inTransaction(
|
||||||
|
session -> {
|
||||||
|
final HibernateCriteriaBuilder criteriaBuilder = session.getCriteriaBuilder();
|
||||||
|
|
||||||
final CriteriaQuery<Object> criteria = criteriaBuilder.createQuery();
|
final CriteriaQuery<Object> criteria = criteriaBuilder.createQuery();
|
||||||
|
final Root<BasicEntity> root = criteria.from( BasicEntity.class );
|
||||||
|
criteria.select( root );
|
||||||
|
criteria.where(
|
||||||
|
criteriaBuilder.equal(
|
||||||
|
criteriaBuilder.literal( 1 ),
|
||||||
|
criteriaBuilder.literal( 1 )
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
final Root<BasicEntity> root = criteria.from( BasicEntity.class );
|
session.createQuery( criteria ).list();
|
||||||
|
}
|
||||||
criteria.select( root );
|
|
||||||
|
|
||||||
criteria.where( criteriaBuilder.equal( criteriaBuilder.literal( 1 ), criteriaBuilder.literal( 1 ) ) );
|
|
||||||
|
|
||||||
inStatelessSession(
|
|
||||||
session -> session.createQuery( criteria ).list()
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testExecutingBasicCriteriaQueryParameterPredicate() {
|
public void testExecutingBasicCriteriaQueryLiteralPredicateInStatelessSession(SessionFactoryScope scope) {
|
||||||
final CriteriaBuilder criteriaBuilder = sessionFactory().getCriteriaBuilder();
|
scope.inStatelessTransaction(
|
||||||
|
session -> {
|
||||||
final CriteriaQuery<Object> criteria = criteriaBuilder.createQuery();
|
final HibernateCriteriaBuilder criteriaBuilder = session.getCriteriaBuilder();
|
||||||
|
final CriteriaQuery<Object> criteria = criteriaBuilder.createQuery();
|
||||||
final Root<BasicEntity> root = criteria.from( BasicEntity.class );
|
final Root<BasicEntity> root = criteria.from( BasicEntity.class );
|
||||||
|
criteria.select( root );
|
||||||
criteria.select( root );
|
criteria.where(
|
||||||
|
criteriaBuilder.equal(
|
||||||
Map<QueryParameterImplementor,Map<SqmParameter, List<JdbcParameter>>> parameterResolutionMap;
|
criteriaBuilder.literal( 1 ),
|
||||||
|
criteriaBuilder.literal( 1 )
|
||||||
final ParameterExpression<Integer> param = criteriaBuilder.parameter( Integer.class );
|
)
|
||||||
|
);
|
||||||
criteria.where( criteriaBuilder.equal( param, param ) );
|
session.createQuery( criteria ).list();
|
||||||
|
}
|
||||||
inSession(
|
|
||||||
session -> session.createQuery( criteria ).setParameter( param, 1 ).list()
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testExecutingBasicCriteriaQueryParameterPredicateInStatelessSession() {
|
public void testExecutingBasicCriteriaQueryParameterPredicate(SessionFactoryScope scope) {
|
||||||
final CriteriaBuilder criteriaBuilder = sessionFactory().getCriteriaBuilder();
|
scope.inStatelessTransaction(
|
||||||
|
session -> {
|
||||||
|
final HibernateCriteriaBuilder criteriaBuilder = session.getCriteriaBuilder();
|
||||||
|
|
||||||
final CriteriaQuery<Object> criteria = criteriaBuilder.createQuery();
|
final CriteriaQuery<Object> criteria = criteriaBuilder.createQuery();
|
||||||
|
final Root<BasicEntity> root = criteria.from( BasicEntity.class );
|
||||||
|
criteria.select( root );
|
||||||
|
final ParameterExpression<Integer> param = criteriaBuilder.parameter( Integer.class );
|
||||||
|
criteria.where( criteriaBuilder.equal( param, param ) );
|
||||||
|
|
||||||
final Root<BasicEntity> root = criteria.from( BasicEntity.class );
|
session.createQuery( criteria ).setParameter( param, 1 ).list();
|
||||||
|
}
|
||||||
criteria.select( root );
|
|
||||||
|
|
||||||
final ParameterExpression<Integer> param = criteriaBuilder.parameter( Integer.class );
|
|
||||||
|
|
||||||
criteria.where( criteriaBuilder.equal( param, param ) );
|
|
||||||
|
|
||||||
inStatelessSession(
|
|
||||||
session -> session.createQuery( criteria ).setParameter( param, 1 ).list()
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCriteriaEntityJoin() {
|
public void testExecutingBasicCriteriaQueryParameterPredicateInStatelessSession(SessionFactoryScope scope) {
|
||||||
final HibernateCriteriaBuilder criteriaBuilder = sessionFactory().getCriteriaBuilder();
|
scope.inStatelessTransaction(
|
||||||
|
session -> {
|
||||||
|
final HibernateCriteriaBuilder criteriaBuilder = session.getCriteriaBuilder();
|
||||||
|
|
||||||
final JpaCriteriaQuery<Object> criteria = criteriaBuilder.createQuery();
|
final CriteriaQuery<Object> criteria = criteriaBuilder.createQuery();
|
||||||
|
final Root<BasicEntity> root = criteria.from( BasicEntity.class );
|
||||||
|
criteria.select( root );
|
||||||
|
final ParameterExpression<Integer> param = criteriaBuilder.parameter( Integer.class );
|
||||||
|
criteria.where( criteriaBuilder.equal( param, param ) );
|
||||||
|
|
||||||
final JpaRoot<BasicEntity> root = criteria.from( BasicEntity.class );
|
session.createQuery( criteria ).setParameter( param, 1 ).list();
|
||||||
root.join( BasicEntity.class );
|
}
|
||||||
|
|
||||||
criteria.select( root );
|
|
||||||
|
|
||||||
inSession(
|
|
||||||
session -> session.createQuery( criteria ).list()
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Entity(name = "BasicEntity")
|
@Test
|
||||||
public static class BasicEntity {
|
public void testCriteriaEntityJoin(SessionFactoryScope scope) {
|
||||||
|
scope.inStatelessTransaction(
|
||||||
|
session -> {
|
||||||
|
final HibernateCriteriaBuilder criteriaBuilder = session.getCriteriaBuilder();
|
||||||
|
|
||||||
@Id
|
final JpaCriteriaQuery<Object> criteria = criteriaBuilder.createQuery();
|
||||||
@GeneratedValue
|
final JpaRoot<BasicEntity> root = criteria.from( BasicEntity.class );
|
||||||
private Integer id;
|
root.join( BasicEntity.class );
|
||||||
|
criteria.select( root );
|
||||||
|
|
||||||
|
session.createQuery( criteria ).list();
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ import java.util.function.Function;
|
||||||
|
|
||||||
import org.hibernate.Interceptor;
|
import org.hibernate.Interceptor;
|
||||||
import org.hibernate.SessionFactoryObserver;
|
import org.hibernate.SessionFactoryObserver;
|
||||||
|
import org.hibernate.StatelessSession;
|
||||||
import org.hibernate.Transaction;
|
import org.hibernate.Transaction;
|
||||||
import org.hibernate.boot.SessionFactoryBuilder;
|
import org.hibernate.boot.SessionFactoryBuilder;
|
||||||
import org.hibernate.boot.registry.StandardServiceRegistry;
|
import org.hibernate.boot.registry.StandardServiceRegistry;
|
||||||
|
@ -231,6 +232,25 @@ public class SessionFactoryExtension
|
||||||
this.sessionFactory = createSessionFactory();
|
this.sessionFactory = createSessionFactory();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SessionFactoryImplementor getSessionFactory() {
|
||||||
|
if ( sessionFactory == null ) {
|
||||||
|
sessionFactory = createSessionFactory();
|
||||||
|
}
|
||||||
|
|
||||||
|
return sessionFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MetadataImplementor getMetadataImplementor() {
|
||||||
|
return modelScope.getDomainModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public StatementInspector getStatementInspector() {
|
||||||
|
return getSessionFactory().getSessionFactoryOptions().getStatementInspector();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
if ( ! active ) {
|
if ( ! active ) {
|
||||||
|
@ -259,15 +279,6 @@ public class SessionFactoryExtension
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public SessionFactoryImplementor getSessionFactory() {
|
|
||||||
if ( sessionFactory == null ) {
|
|
||||||
sessionFactory = createSessionFactory();
|
|
||||||
}
|
|
||||||
|
|
||||||
return sessionFactory;
|
|
||||||
}
|
|
||||||
|
|
||||||
private SessionFactoryImplementor createSessionFactory() {
|
private SessionFactoryImplementor createSessionFactory() {
|
||||||
if ( ! active ) {
|
if ( ! active ) {
|
||||||
throw new IllegalStateException( "SessionFactoryScope is no longer active" );
|
throw new IllegalStateException( "SessionFactoryScope is no longer active" );
|
||||||
|
@ -415,13 +426,76 @@ public class SessionFactoryExtension
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MetadataImplementor getMetadataImplementor() {
|
public void inStatelessSession(Consumer<StatelessSession> action) {
|
||||||
return modelScope.getDomainModel();
|
log.trace( "#inStatelessSession(Consumer)" );
|
||||||
|
|
||||||
|
try ( final StatelessSession statelessSession = getSessionFactory().openStatelessSession(); ) {
|
||||||
|
log.trace( "StatelessSession opened, calling action" );
|
||||||
|
action.accept( statelessSession );
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
log.trace( "StatelessSession close - auto-close block" );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public StatementInspector getStatementInspector() {
|
public void inStatelessTransaction(Consumer<StatelessSession> action) {
|
||||||
return getSessionFactory().getSessionFactoryOptions().getStatementInspector();
|
log.trace( "#inStatelessTransaction(Consumer)" );
|
||||||
|
|
||||||
|
try ( final StatelessSession statelessSession = getSessionFactory().openStatelessSession(); ) {
|
||||||
|
log.trace( "StatelessSession opened, calling action" );
|
||||||
|
inStatelessTransaction( statelessSession, action );
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
log.trace( "StatelessSession close - auto-close block" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void inStatelessTransaction(StatelessSession session, Consumer<StatelessSession> action) {
|
||||||
|
log.trace( "inStatelessTransaction(StatelessSession,Consumer)" );
|
||||||
|
|
||||||
|
final Transaction txn = session.beginTransaction();
|
||||||
|
log.trace( "Started transaction" );
|
||||||
|
|
||||||
|
try {
|
||||||
|
log.trace( "Calling action in txn" );
|
||||||
|
action.accept( session );
|
||||||
|
log.trace( "Called action - in txn" );
|
||||||
|
|
||||||
|
if ( !txn.getRollbackOnly() ) {
|
||||||
|
log.trace( "Committing transaction" );
|
||||||
|
txn.commit();
|
||||||
|
log.trace( "Committed transaction" );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
try {
|
||||||
|
log.trace( "Rollback transaction marked for rollback only" );
|
||||||
|
txn.rollback();
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
log.error( "Rollback failure", e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
log.tracef(
|
||||||
|
"Error calling action: %s (%s) - rolling back",
|
||||||
|
e.getClass().getName(),
|
||||||
|
e.getMessage()
|
||||||
|
);
|
||||||
|
try {
|
||||||
|
txn.rollback();
|
||||||
|
}
|
||||||
|
catch (Exception ignore) {
|
||||||
|
log.trace( "Was unable to roll back transaction" );
|
||||||
|
// really nothing else we can do here - the attempt to
|
||||||
|
// rollback already failed and there is nothing else
|
||||||
|
// to clean up.
|
||||||
|
}
|
||||||
|
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ package org.hibernate.testing.orm.junit;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import org.hibernate.StatelessSession;
|
||||||
import org.hibernate.boot.spi.MetadataImplementor;
|
import org.hibernate.boot.spi.MetadataImplementor;
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.engine.spi.SessionImplementor;
|
import org.hibernate.engine.spi.SessionImplementor;
|
||||||
|
@ -19,18 +20,18 @@ import org.hibernate.resource.jdbc.spi.StatementInspector;
|
||||||
*/
|
*/
|
||||||
public interface SessionFactoryScope {
|
public interface SessionFactoryScope {
|
||||||
SessionFactoryImplementor getSessionFactory();
|
SessionFactoryImplementor getSessionFactory();
|
||||||
|
MetadataImplementor getMetadataImplementor();
|
||||||
|
StatementInspector getStatementInspector();
|
||||||
|
|
||||||
void inSession(Consumer<SessionImplementor> action);
|
void inSession(Consumer<SessionImplementor> action);
|
||||||
|
|
||||||
void inTransaction(Consumer<SessionImplementor> action);
|
void inTransaction(Consumer<SessionImplementor> action);
|
||||||
void inTransaction(SessionImplementor session, Consumer<SessionImplementor> action);
|
void inTransaction(SessionImplementor session, Consumer<SessionImplementor> action);
|
||||||
|
|
||||||
<T> T fromSession(Function<SessionImplementor, T> action);
|
<T> T fromSession(Function<SessionImplementor, T> action);
|
||||||
|
|
||||||
<T> T fromTransaction(Function<SessionImplementor, T> action);
|
<T> T fromTransaction(Function<SessionImplementor, T> action);
|
||||||
<T> T fromTransaction(SessionImplementor session, Function<SessionImplementor, T> action);
|
<T> T fromTransaction(SessionImplementor session, Function<SessionImplementor, T> action);
|
||||||
|
|
||||||
MetadataImplementor getMetadataImplementor();
|
void inStatelessSession(Consumer<StatelessSession> action);
|
||||||
|
void inStatelessTransaction(Consumer<StatelessSession> action);
|
||||||
StatementInspector getStatementInspector();
|
void inStatelessTransaction(StatelessSession session, Consumer<StatelessSession> action);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue