Skip to content

Commit

Permalink
HHH-18979 simplify Range.toPredicate signature
Browse files Browse the repository at this point in the history
  • Loading branch information
gavinking committed Dec 25, 2024
1 parent 78e03f5 commit 48af9bb
Show file tree
Hide file tree
Showing 10 changed files with 26 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,6 @@ public Restriction<X> negated() {

@Override
public Predicate toPredicate(Root<? extends X> root, CriteriaBuilder builder) {
return range.toPredicate( root, attribute, builder );
return range.toPredicate( root.get( attribute ), builder );
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,14 @@ public Predicate toPredicate(Root<? extends X> root, CriteriaBuilder builder) {
if ( !entity.isAssignableFrom( entityType.getJavaType() ) ) {
throw new IllegalArgumentException( "Root entity is not a subtype of '" + entity.getTypeName() + "'" );
}
final Attribute<?, ?> att = entityType.getAttribute( attributeName );
if ( !range.getType().isAssignableFrom( att.getJavaType() ) ) {
final Attribute<?, ?> attribute = entityType.getAttribute( attributeName );
if ( !(attribute instanceof SingularAttribute) ) {
throw new IllegalArgumentException( "Attribute '" + attributeName + "' is not singular" );
}
if ( !range.getType().isAssignableFrom( attribute.getJavaType() ) ) {
throw new IllegalArgumentException( "Attribute '" + attributeName
+ "' is not assignable to range of type '" + range.getType().getName() + "'" );
}
if ( !(att instanceof SingularAttribute) ) {
throw new IllegalArgumentException( "Attribute '" + attributeName + "' is not singular" );
}
@SuppressWarnings("unchecked")
final SingularAttribute<X, U> attribute = (SingularAttribute<X, U>) att;
return range.toPredicate( root, attribute, builder );
return range.toPredicate( root.get( attributeName ), builder );
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import jakarta.persistence.criteria.Expression;
import jakarta.persistence.criteria.Path;
import jakarta.persistence.criteria.Predicate;
import jakarta.persistence.metamodel.SingularAttribute;

import java.util.Locale;

Expand All @@ -17,13 +16,13 @@
*/
record CaseInsensitiveValue(String value) implements Range<String> {
@Override
public <X> Predicate toPredicate(Path<? extends X> root, SingularAttribute<X, String> attribute, CriteriaBuilder builder) {
public Predicate toPredicate(Path<String> path, CriteriaBuilder builder) {
// TODO: it would be much better to not do use literal,
// and let it be treated as a parameter, but we
// we run into the usual bug with parameters in
// manipulated SQM trees
final Expression<String> literal = builder.literal( value.toLowerCase( Locale.ROOT ) );
return builder.lower( root.get( attribute ) ).equalTo( literal );
return builder.lower( path ).equalTo( literal );
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,17 @@
import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.Path;
import jakarta.persistence.criteria.Predicate;
import jakarta.persistence.metamodel.SingularAttribute;

/**
* Restricts to an upper-bounded and lower-bounded interval.
*/
record Interval<U extends Comparable<U>>(LowerBound<U> lowerBound, UpperBound<U> upperBound)
implements Range<U> {
@Override
public <X> Predicate toPredicate(Path<? extends X> root, SingularAttribute<X, U> attribute, CriteriaBuilder builder) {
public Predicate toPredicate(Path<U> path, CriteriaBuilder builder) {
return lowerBound.open() || upperBound.open()
? builder.and( lowerBound.toPredicate( root, attribute, builder ),
upperBound.toPredicate( root, attribute, builder ) )
: builder.between( root.get( attribute ),
builder.literal( lowerBound.bound() ), builder.literal( upperBound.bound() ) );
? builder.and( lowerBound.toPredicate( path, builder ), upperBound.toPredicate( path, builder ) )
: builder.between( path, builder.literal( lowerBound.bound() ), builder.literal( upperBound.bound() ) );
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,21 @@
import jakarta.persistence.criteria.Expression;
import jakarta.persistence.criteria.Path;
import jakarta.persistence.criteria.Predicate;
import jakarta.persistence.metamodel.SingularAttribute;

/**
* Restricts to all values higher than a given lower bound.
*/
record LowerBound<U extends Comparable<U>>(U bound, boolean open) implements Range<U> {
@Override
public <X> Predicate toPredicate(Path<? extends X> root, SingularAttribute<X, U> attribute, CriteriaBuilder builder) {
public Predicate toPredicate(Path<U> path, CriteriaBuilder builder) {
// TODO: it would be much better to not do use literal,
// and let it be treated as a parameter, but we
// we run into the usual bug with parameters in
// manipulated SQM trees
final Expression<U> literal = builder.literal( bound );
return open
? builder.greaterThan( root.get( attribute ), literal )
: builder.greaterThanOrEqualTo( root.get( attribute ), literal );
? builder.greaterThan( path, literal )
: builder.greaterThanOrEqualTo( path, literal );
}

@Override @SuppressWarnings("unchecked")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.Path;
import jakarta.persistence.criteria.Predicate;
import jakarta.persistence.metamodel.SingularAttribute;

import java.util.Locale;

Expand All @@ -16,10 +15,10 @@
*/
record Pattern(String pattern, boolean caseSensitive) implements Range<String> {
@Override
public <X> Predicate toPredicate(Path<? extends X> root, SingularAttribute<X, String> attribute, CriteriaBuilder builder) {
public Predicate toPredicate(Path<String> path, CriteriaBuilder builder) {
return caseSensitive
? builder.like( root.get( attribute ), builder.literal( pattern ) )
: builder.like( builder.lower( root.get( attribute ) ),
? builder.like( path, builder.literal( pattern ) )
: builder.like( builder.lower( path ),
builder.literal( pattern.toLowerCase( Locale.ROOT ) ) );
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.Path;
import jakarta.persistence.criteria.Predicate;
import jakarta.persistence.metamodel.SingularAttribute;
import org.hibernate.Incubating;
import org.hibernate.Internal;
import org.hibernate.query.Restriction;
Expand Down Expand Up @@ -36,7 +35,7 @@ public interface Range<U> {
* values.
*/
@Internal
<X> Predicate toPredicate(Path<? extends X> root, SingularAttribute<X, U> attribute, CriteriaBuilder builder);
Predicate toPredicate(Path<U> path, CriteriaBuilder builder);

static <U> Range<U> singleValue(U value) {
return new Value<>( value );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,21 @@
import jakarta.persistence.criteria.Expression;
import jakarta.persistence.criteria.Path;
import jakarta.persistence.criteria.Predicate;
import jakarta.persistence.metamodel.SingularAttribute;

/**
* Restricts to all values lower than a given upper bound.
*/
record UpperBound<U extends Comparable<U>>(U bound, boolean open) implements Range<U> {
@Override
public <X> Predicate toPredicate(Path<? extends X> root, SingularAttribute<X, U> attribute, CriteriaBuilder builder) {
public Predicate toPredicate(Path<U> path, CriteriaBuilder builder) {
// TODO: it would be much better to not do use literal,
// and let it be treated as a parameter, but we
// we run into the usual bug with parameters in
// manipulated SQM trees
final Expression<U> literal = builder.literal( bound );
return open
? builder.lessThan( root.get( attribute ), literal )
: builder.lessThanOrEqualTo( root.get( attribute ), literal );
? builder.lessThan( path, literal )
: builder.lessThanOrEqualTo( path, literal );
}

@Override @SuppressWarnings("unchecked")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,19 @@
import jakarta.persistence.criteria.Expression;
import jakarta.persistence.criteria.Path;
import jakarta.persistence.criteria.Predicate;
import jakarta.persistence.metamodel.SingularAttribute;

/**
* Restricts to a single literal value.
*/
record Value<U>(U value) implements Range<U> {
@Override
public <X> Predicate toPredicate(Path<? extends X> root, SingularAttribute<X, U> attribute, CriteriaBuilder builder) {
public Predicate toPredicate(Path<U> path, CriteriaBuilder builder) {
// TODO: it would be much better to not do use literal,
// and let it be treated as a parameter, but we
// we run into the usual bug with parameters in
// manipulated SQM trees
final Expression<U> literal = builder.literal( value );
return root.get( attribute ).equalTo( literal );
return path.equalTo( literal );
}

@Override @SuppressWarnings("unchecked")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.Path;
import jakarta.persistence.criteria.Predicate;
import jakarta.persistence.metamodel.SingularAttribute;

import java.util.List;

Expand All @@ -16,8 +15,8 @@
*/
record ValueList<U>(List<U> values) implements Range<U> {
@Override
public <X> Predicate toPredicate(Path<? extends X> root, SingularAttribute<X, U> attribute, CriteriaBuilder builder) {
return root.get( attribute ).in( values.stream().map( builder::literal ).toList() );
public Predicate toPredicate(Path<U> path, CriteriaBuilder builder) {
return path.in( values.stream().map( builder::literal ).toList() );
}

@Override @SuppressWarnings("unchecked")
Expand Down

0 comments on commit 48af9bb

Please sign in to comment.