HHH-16899 avoid capturing the Session in CriteriaDefinition [as suggested by Sanne]

This commit is contained in:
Gavin King 2023-07-05 18:55:10 +02:00
parent 2d92edd6bb
commit b4b2b295fc
2 changed files with 227 additions and 219 deletions

View File

@ -10,6 +10,7 @@ import jakarta.persistence.criteria.*;
import jakarta.persistence.metamodel.EntityType;
import org.hibernate.Incubating;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.query.SelectionQuery;
import org.hibernate.query.criteria.spi.HibernateCriteriaBuilderDelegate;
import org.hibernate.query.sqm.FetchClauseType;
@ -48,256 +49,258 @@ import java.util.function.Function;
*/
@Incubating
public abstract class CriteriaDefinition<R>
extends HibernateCriteriaBuilderDelegate
implements JpaCriteriaQuery<R> {
extends HibernateCriteriaBuilderDelegate
implements JpaCriteriaQuery<R> {
private final Session session;
private final JpaCriteriaQuery<R> query;
private final JpaCriteriaQuery<R> query;
public CriteriaDefinition(Session session, Class<R> resultType) {
super( session.getSessionFactory().getCriteriaBuilder() );
this.session = session;
query = createQuery( resultType );
define();
}
public CriteriaDefinition(SessionFactory factory, Class<R> resultType) {
super( factory.getCriteriaBuilder() );
query = createQuery( resultType );
define();
}
public SelectionQuery<R> createSelectionQuery() {
return session.createSelectionQuery(query);
}
public CriteriaDefinition(Session session, Class<R> resultType) {
this( session.getSessionFactory(), resultType );
}
public abstract void define();
public SelectionQuery<R> createSelectionQuery(Session session) {
return session.createSelectionQuery(query);
}
@Override
public JpaCriteriaQuery<R> select(Selection<? extends R> selection) {
return query.select(selection);
}
public abstract void define();
@Override
public JpaCriteriaQuery<R> multiselect(Selection<?>... selections) {
return query.multiselect(selections);
}
@Override
public JpaCriteriaQuery<R> select(Selection<? extends R> selection) {
return query.select(selection);
}
@Override
public JpaCriteriaQuery<R> multiselect(List<Selection<?>> list) {
return query.multiselect(list);
}
@Override
public JpaCriteriaQuery<R> multiselect(Selection<?>... selections) {
return query.multiselect(selections);
}
@Override
public JpaCriteriaQuery<R> where(Expression<Boolean> restriction) {
return query.where(restriction);
}
@Override
public JpaCriteriaQuery<R> multiselect(List<Selection<?>> list) {
return query.multiselect(list);
}
@Override
public JpaCriteriaQuery<R> where(Predicate... restrictions) {
return query.where(restrictions);
}
@Override
public JpaCriteriaQuery<R> where(Expression<Boolean> restriction) {
return query.where(restriction);
}
@Override
public JpaCriteriaQuery<R> groupBy(Expression... grouping) {
return query.groupBy(grouping);
}
@Override
public JpaCriteriaQuery<R> where(Predicate... restrictions) {
return query.where(restrictions);
}
@Override
public JpaCriteriaQuery<R> groupBy(List<Expression<?>> grouping) {
return query.groupBy(grouping);
}
@Override
public JpaCriteriaQuery<R> groupBy(Expression... grouping) {
return query.groupBy(grouping);
}
@Override
public JpaCriteriaQuery<R> having(Expression<Boolean> restriction) {
return query.having(restriction);
}
@Override
public JpaCriteriaQuery<R> groupBy(List<Expression<?>> grouping) {
return query.groupBy(grouping);
}
@Override
public JpaCriteriaQuery<R> having(Predicate... restrictions) {
return query.having(restrictions);
}
@Override
public JpaCriteriaQuery<R> having(Expression<Boolean> restriction) {
return query.having(restriction);
}
@Override
public JpaCriteriaQuery<R> orderBy(Order... o) {
return query.orderBy(o);
}
@Override
public JpaCriteriaQuery<R> having(Predicate... restrictions) {
return query.having(restrictions);
}
@Override
public JpaCriteriaQuery<R> orderBy(List<Order> o) {
return query.orderBy(o);
}
@Override
public JpaCriteriaQuery<R> orderBy(Order... o) {
return query.orderBy(o);
}
@Override
public JpaCriteriaQuery<R> distinct(boolean distinct) {
return query.distinct(distinct);
}
@Override
public JpaCriteriaQuery<R> orderBy(List<Order> o) {
return query.orderBy(o);
}
@Override
public List<Order> getOrderList() {
return query.getOrderList();
}
@Override
public JpaCriteriaQuery<R> distinct(boolean distinct) {
return query.distinct(distinct);
}
@Override
public Set<ParameterExpression<?>> getParameters() {
return query.getParameters();
}
@Override
public List<Order> getOrderList() {
return query.getOrderList();
}
@Override
public <X> JpaRoot<X> from(Class<X> entityClass) {
return query.from(entityClass);
}
@Override
public Set<ParameterExpression<?>> getParameters() {
return query.getParameters();
}
@Override
public <X> JpaRoot<X> from(EntityType<X> entity) {
return query.from(entity);
}
@Override
public <X> JpaRoot<X> from(Class<X> entityClass) {
return query.from(entityClass);
}
@Override
public <U> JpaSubQuery<U> subquery(Class<U> type) {
return query.subquery(type);
}
@Override
public <X> JpaRoot<X> from(EntityType<X> entity) {
return query.from(entity);
}
@Override
public Set<Root<?>> getRoots() {
return query.getRoots();
}
@Override
public <U> JpaSubQuery<U> subquery(Class<U> type) {
return query.subquery(type);
}
@Override
public JpaSelection<R> getSelection() {
return query.getSelection();
}
@Override
public Set<Root<?>> getRoots() {
return query.getRoots();
}
@Override
public List<Expression<?>> getGroupList() {
return query.getGroupList();
}
@Override
public JpaSelection<R> getSelection() {
return query.getSelection();
}
@Override
public JpaPredicate getGroupRestriction() {
return query.getGroupRestriction();
}
@Override
public List<Expression<?>> getGroupList() {
return query.getGroupList();
}
@Override
public boolean isDistinct() {
return query.isDistinct();
}
@Override
public JpaPredicate getGroupRestriction() {
return query.getGroupRestriction();
}
@Override
public Class<R> getResultType() {
return query.getResultType();
}
@Override
public boolean isDistinct() {
return query.isDistinct();
}
@Override
public JpaPredicate getRestriction() {
return query.getRestriction();
}
@Override
public Class<R> getResultType() {
return query.getResultType();
}
@Override
public JpaExpression<Number> getOffset() {
return query.getOffset();
}
@Override
public JpaPredicate getRestriction() {
return query.getRestriction();
}
@Override
public JpaCriteriaQuery<R> offset(JpaExpression<? extends Number> offset) {
return query.offset(offset);
}
@Override
public JpaExpression<Number> getOffset() {
return query.getOffset();
}
@Override
public JpaCriteriaQuery<R> offset(Number offset) {
return query.offset(offset);
}
@Override
public JpaCriteriaQuery<R> offset(JpaExpression<? extends Number> offset) {
return query.offset(offset);
}
@Override
public JpaExpression<Number> getFetch() {
return query.getFetch();
}
@Override
public JpaCriteriaQuery<R> offset(Number offset) {
return query.offset(offset);
}
@Override
public JpaCriteriaQuery<R> fetch(JpaExpression<? extends Number> fetch) {
return query.fetch(fetch);
}
@Override
public JpaExpression<Number> getFetch() {
return query.getFetch();
}
@Override
public JpaCriteriaQuery<R> fetch(JpaExpression<? extends Number> fetch, FetchClauseType fetchClauseType) {
return query.fetch(fetch, fetchClauseType);
}
@Override
public JpaCriteriaQuery<R> fetch(JpaExpression<? extends Number> fetch) {
return query.fetch(fetch);
}
@Override
public JpaCriteriaQuery<R> fetch(Number fetch) {
return query.fetch(fetch);
}
@Override
public JpaCriteriaQuery<R> fetch(JpaExpression<? extends Number> fetch, FetchClauseType fetchClauseType) {
return query.fetch(fetch, fetchClauseType);
}
@Override
public JpaCriteriaQuery<R> fetch(Number fetch, FetchClauseType fetchClauseType) {
return query.fetch(fetch, fetchClauseType);
}
@Override
public JpaCriteriaQuery<R> fetch(Number fetch) {
return query.fetch(fetch);
}
@Override
public FetchClauseType getFetchClauseType() {
return query.getFetchClauseType();
}
@Override
public JpaCriteriaQuery<R> fetch(Number fetch, FetchClauseType fetchClauseType) {
return query.fetch(fetch, fetchClauseType);
}
@Override
public List<Root<?>> getRootList() {
return query.getRootList();
}
@Override
public FetchClauseType getFetchClauseType() {
return query.getFetchClauseType();
}
@Override
public Collection<? extends JpaCteCriteria<?>> getCteCriterias() {
return query.getCteCriterias();
}
@Override
public List<Root<?>> getRootList() {
return query.getRootList();
}
@Override
public <T> JpaCteCriteria<T> getCteCriteria(String cteName) {
return query.getCteCriteria(cteName);
}
@Override
public Collection<? extends JpaCteCriteria<?>> getCteCriterias() {
return query.getCteCriterias();
}
@Override
public <T> JpaCteCriteria<T> with(AbstractQuery<T> criteria) {
return query.with(criteria);
}
@Override
public <T> JpaCteCriteria<T> getCteCriteria(String cteName) {
return query.getCteCriteria(cteName);
}
@Override
public <T> JpaCteCriteria<T> withRecursiveUnionAll(AbstractQuery<T> baseCriteria, Function<JpaCteCriteria<T>, AbstractQuery<T>> recursiveCriteriaProducer) {
return query.withRecursiveUnionAll(baseCriteria, recursiveCriteriaProducer);
}
@Override
public <T> JpaCteCriteria<T> with(AbstractQuery<T> criteria) {
return query.with(criteria);
}
@Override
public <T> JpaCteCriteria<T> withRecursiveUnionDistinct(AbstractQuery<T> baseCriteria, Function<JpaCteCriteria<T>, AbstractQuery<T>> recursiveCriteriaProducer) {
return query.withRecursiveUnionDistinct(baseCriteria, recursiveCriteriaProducer);
}
@Override
public <T> JpaCteCriteria<T> withRecursiveUnionAll(AbstractQuery<T> baseCriteria, Function<JpaCteCriteria<T>, AbstractQuery<T>> recursiveCriteriaProducer) {
return query.withRecursiveUnionAll(baseCriteria, recursiveCriteriaProducer);
}
@Override
public <T> JpaCteCriteria<T> with(String name, AbstractQuery<T> criteria) {
return query.with(name, criteria);
}
@Override
public <T> JpaCteCriteria<T> withRecursiveUnionDistinct(AbstractQuery<T> baseCriteria, Function<JpaCteCriteria<T>, AbstractQuery<T>> recursiveCriteriaProducer) {
return query.withRecursiveUnionDistinct(baseCriteria, recursiveCriteriaProducer);
}
@Override
public <T> JpaCteCriteria<T> withRecursiveUnionAll(
String name, AbstractQuery<T> baseCriteria,
Function<JpaCteCriteria<T>, AbstractQuery<T>> recursiveCriteriaProducer) {
return query.withRecursiveUnionAll(name, baseCriteria, recursiveCriteriaProducer);
}
@Override
public <T> JpaCteCriteria<T> with(String name, AbstractQuery<T> criteria) {
return query.with(name, criteria);
}
@Override
public <T> JpaCteCriteria<T> withRecursiveUnionDistinct(
String name, AbstractQuery<T> baseCriteria,
Function<JpaCteCriteria<T>, AbstractQuery<T>> recursiveCriteriaProducer) {
return query.withRecursiveUnionDistinct(name, baseCriteria, recursiveCriteriaProducer);
}
@Override
public <T> JpaCteCriteria<T> withRecursiveUnionAll(
String name, AbstractQuery<T> baseCriteria,
Function<JpaCteCriteria<T>, AbstractQuery<T>> recursiveCriteriaProducer) {
return query.withRecursiveUnionAll(name, baseCriteria, recursiveCriteriaProducer);
}
@Override
public JpaQueryStructure<R> getQuerySpec() {
return query.getQuerySpec();
}
@Override
public <T> JpaCteCriteria<T> withRecursiveUnionDistinct(
String name, AbstractQuery<T> baseCriteria,
Function<JpaCteCriteria<T>, AbstractQuery<T>> recursiveCriteriaProducer) {
return query.withRecursiveUnionDistinct(name, baseCriteria, recursiveCriteriaProducer);
}
@Override
public JpaQueryPart<R> getQueryPart() {
return query.getQueryPart();
}
@Override
public JpaQueryStructure<R> getQuerySpec() {
return query.getQuerySpec();
}
@Override
public <X> JpaDerivedRoot<X> from(Subquery<X> subquery) {
return query.from(subquery);
}
@Override
public JpaQueryPart<R> getQueryPart() {
return query.getQueryPart();
}
@Override
public <X> JpaRoot<X> from(JpaCteCriteria<X> cte) {
return query.from(cte);
}
@Override
public <X> JpaDerivedRoot<X> from(Subquery<X> subquery) {
return query.from(subquery);
}
@Override
public <X> JpaRoot<X> from(JpaCteCriteria<X> cte) {
return query.from(cte);
}
}

View File

@ -2,6 +2,7 @@ package org.hibernate.orm.test.jpa.criteria.query;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.query.criteria.CriteriaDefinition;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.SessionFactory;
@ -21,29 +22,33 @@ public class CriteriaDefinitionTest {
s.persist( new Message(2L, "bye") );
});
SessionFactoryImplementor sessionFactory = scope.getSessionFactory();
var query1 = new CriteriaDefinition<>(sessionFactory, Object[].class) {
public void define() {
var m = from(Message.class);
select(array(m.get("id"), m.get("text")));
where(like(m.get("text"), "hell%"), m.get("id").equalTo(1));
orderBy(asc(m.get("id")));
}
};
var query2 = new CriteriaDefinition<>(sessionFactory, Message.class) {
public void define() {
var m = from(Message.class);
where(like(m.get("text"), "hell%"), m.get("id").equalTo(1));
orderBy(asc(m.get("id")));
}
};
scope.inSession(session -> {
var idAndText = new CriteriaDefinition<>(session, Object[].class) {
public void define() {
var m = from(Message.class);
select(array(m.get("id"), m.get("text")));
where(like(m.get("text"), "hell%"), m.get("id").equalTo(1));
orderBy(asc(m.get("id")));
}
}.createSelectionQuery()
.getSingleResult();
var idAndText = query1.createSelectionQuery(session).getSingleResult();
assertNotNull(idAndText);
assertEquals(1L,idAndText[0]);
assertEquals("hello",idAndText[1]);
var message = new CriteriaDefinition<>(session, Message.class) {
public void define() {
var m = from(Message.class);
where(like(m.get("text"), "hell%"), m.get("id").equalTo(1));
orderBy(asc(m.get("id")));
}
}.createSelectionQuery()
.getSingleResult();
var message = query2.createSelectionQuery(session).getSingleResult();
assertNotNull(message);
assertEquals(1L,message.id);