HHH-16899 avoid capturing the Session in CriteriaDefinition [as suggested by Sanne]
This commit is contained in:
parent
2d92edd6bb
commit
b4b2b295fc
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue