HHH-4698 - Better handling of JPA criteria expressions
git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@18398 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
parent
ef1cb9f066
commit
33b7b6c803
|
@ -59,7 +59,7 @@ import org.slf4j.LoggerFactory;
|
|||
|
||||
import org.hibernate.*;
|
||||
import org.hibernate.cfg.Environment;
|
||||
import org.hibernate.ejb.criteria.ValueConverter;
|
||||
import org.hibernate.ejb.criteria.ValueHandlerFactory;
|
||||
import org.hibernate.ejb.transaction.JoinableCMTTransaction;
|
||||
import org.hibernate.ejb.util.ConfigurationHelper;
|
||||
import org.hibernate.ejb.criteria.CriteriaQueryCompiler;
|
||||
|
@ -148,8 +148,8 @@ public abstract class AbstractEntityManagerImpl implements HibernateEntityManage
|
|||
Options options) {
|
||||
try {
|
||||
org.hibernate.Query hqlQuery = getSession().createQuery( jpaqlString );
|
||||
if ( options.getConversions() != null ) {
|
||||
hqlQuery.setResultTransformer( new ValueConversionResultTransformer( options.getConversions() ) );
|
||||
if ( options.getValueHandlers() != null ) {
|
||||
hqlQuery.setResultTransformer( new ValueConversionResultTransformer( options.getValueHandlers() ) );
|
||||
}
|
||||
else {
|
||||
options.getResultMetadataValidator().validate( hqlQuery.getReturnTypes() );
|
||||
|
@ -162,20 +162,20 @@ public abstract class AbstractEntityManagerImpl implements HibernateEntityManage
|
|||
}
|
||||
|
||||
private static class ValueConversionResultTransformer extends BasicTransformerAdapter {
|
||||
private List<ValueConverter.Conversion> conversions;
|
||||
private List<ValueHandlerFactory.ValueHandler> valueHandlers;
|
||||
|
||||
private ValueConversionResultTransformer(List<ValueConverter.Conversion> conversions) {
|
||||
this.conversions = conversions;
|
||||
private ValueConversionResultTransformer(List<ValueHandlerFactory.ValueHandler> valueHandlers) {
|
||||
this.valueHandlers = valueHandlers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object transformTuple(Object[] tuple, String[] aliases) {
|
||||
Object[] result = new Object[ tuple.length ];
|
||||
for ( int i = 0; i < tuple.length; i++ ) {
|
||||
ValueConverter.Conversion conversion = conversions.get( i );
|
||||
result[i] = conversion == null
|
||||
ValueHandlerFactory.ValueHandler valueHandler = valueHandlers.get( i );
|
||||
result[i] = valueHandler == null
|
||||
? tuple[i]
|
||||
: conversion.apply( tuple[i] );
|
||||
: valueHandler.convert( tuple[i] );
|
||||
}
|
||||
return result.length == 1 ? result[0] : result;
|
||||
}
|
||||
|
|
|
@ -30,8 +30,7 @@ import javax.persistence.TypedQuery;
|
|||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.StaleStateException;
|
||||
import org.hibernate.LockOptions;
|
||||
import org.hibernate.ejb.criteria.ValueConverter;
|
||||
import org.hibernate.transform.ResultTransformer;
|
||||
import org.hibernate.ejb.criteria.ValueHandlerFactory;
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -124,7 +123,7 @@ public interface HibernateEntityManagerImplementor extends HibernateEntityManage
|
|||
*
|
||||
* @return Value conversions to be applied to the JPA QL results
|
||||
*/
|
||||
public List<ValueConverter.Conversion> getConversions();
|
||||
public List<ValueHandlerFactory.ValueHandler> getValueHandlers();
|
||||
|
||||
/**
|
||||
* Get the explicit parameter types. Generally speaking these would apply to implicit named
|
||||
|
|
|
@ -48,7 +48,6 @@ import org.hibernate.ejb.criteria.expression.CoalesceExpression;
|
|||
import org.hibernate.ejb.criteria.expression.CollectionExpression;
|
||||
import org.hibernate.ejb.criteria.expression.CompoundSelectionImpl;
|
||||
import org.hibernate.ejb.criteria.expression.ConcatExpression;
|
||||
import org.hibernate.ejb.criteria.ExpressionImplementor;
|
||||
import org.hibernate.ejb.criteria.expression.ParameterExpressionImpl;
|
||||
import org.hibernate.ejb.criteria.expression.LiteralExpression;
|
||||
import org.hibernate.ejb.criteria.expression.NullifExpression;
|
||||
|
@ -71,6 +70,7 @@ import org.hibernate.ejb.criteria.expression.function.SqrtFunction;
|
|||
import org.hibernate.ejb.criteria.expression.function.SubstringFunction;
|
||||
import org.hibernate.ejb.criteria.expression.function.TrimFunction;
|
||||
import org.hibernate.ejb.criteria.expression.function.UpperFunction;
|
||||
import org.hibernate.ejb.criteria.predicate.BooleanAssertionPredicate;
|
||||
import org.hibernate.ejb.criteria.predicate.BooleanExpressionPredicate;
|
||||
import org.hibernate.ejb.criteria.predicate.NullnessPredicate;
|
||||
import org.hibernate.ejb.criteria.predicate.CompoundPredicate;
|
||||
|
@ -252,6 +252,9 @@ public class CriteriaBuilderImpl implements CriteriaBuilder, Serializable {
|
|||
if ( Predicate.class.isInstance( expression ) ) {
|
||||
return ( ( Predicate ) expression );
|
||||
}
|
||||
else if ( PathImplementor.class.isInstance( expression ) ) {
|
||||
return new BooleanAssertionPredicate( this, expression, Boolean.TRUE );
|
||||
}
|
||||
else {
|
||||
return new BooleanExpressionPredicate( this, expression );
|
||||
}
|
||||
|
@ -309,19 +312,15 @@ public class CriteriaBuilderImpl implements CriteriaBuilder, Serializable {
|
|||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public Predicate isTrue(Expression<Boolean> x) {
|
||||
return wrap( x );
|
||||
// TODO : the correct thing here depends on response to #5 on my wiki page
|
||||
// return new ExplicitTruthValueCheck( this, x, TruthValue.TRUE );
|
||||
public Predicate isTrue(Expression<Boolean> expression) {
|
||||
return new BooleanAssertionPredicate( this, expression, Boolean.TRUE );
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public Predicate isFalse(Expression<Boolean> x) {
|
||||
return wrap( x ).not();
|
||||
// TODO : the correct thing here depends on response to #5 on my wiki page
|
||||
// return new ExplicitTruthValueCheck( this, x, TruthValue.FALSE );
|
||||
public Predicate isFalse(Expression<Boolean> expression) {
|
||||
return new BooleanAssertionPredicate( this, expression, Boolean.FALSE );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1122,10 +1121,11 @@ public class CriteriaBuilderImpl implements CriteriaBuilder, Serializable {
|
|||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
public <Y> Expression<Y> all(Subquery<Y> subquery) {
|
||||
return new SubqueryComparisonModifierExpression<Y>(
|
||||
this,
|
||||
(Class)subquery.getJavaType(),
|
||||
(Class<Y>) subquery.getJavaType(),
|
||||
subquery,
|
||||
SubqueryComparisonModifierExpression.Modifier.ALL
|
||||
);
|
||||
|
@ -1134,10 +1134,11 @@ public class CriteriaBuilderImpl implements CriteriaBuilder, Serializable {
|
|||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
public <Y> Expression<Y> some(Subquery<Y> subquery) {
|
||||
return new SubqueryComparisonModifierExpression<Y>(
|
||||
this,
|
||||
(Class)subquery.getJavaType(),
|
||||
(Class<Y>) subquery.getJavaType(),
|
||||
subquery,
|
||||
SubqueryComparisonModifierExpression.Modifier.SOME
|
||||
);
|
||||
|
@ -1146,10 +1147,11 @@ public class CriteriaBuilderImpl implements CriteriaBuilder, Serializable {
|
|||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
public <Y> Expression<Y> any(Subquery<Y> subquery) {
|
||||
return new SubqueryComparisonModifierExpression<Y>(
|
||||
this,
|
||||
(Class)subquery.getJavaType(),
|
||||
(Class<Y>) subquery.getJavaType(),
|
||||
subquery,
|
||||
SubqueryComparisonModifierExpression.Modifier.ANY
|
||||
);
|
||||
|
@ -1161,8 +1163,9 @@ public class CriteriaBuilderImpl implements CriteriaBuilder, Serializable {
|
|||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@SuppressWarnings({ "RedundantCast" })
|
||||
public <Y> Expression<Y> coalesce(Expression<? extends Y> exp1, Expression<? extends Y> exp2) {
|
||||
return coalesce( (Class<Y>)null, exp1, exp2 );
|
||||
return coalesce( (Class<Y>) null, exp1, exp2 );
|
||||
}
|
||||
|
||||
public <Y> Expression<Y> coalesce(Class<Y> type, Expression<? extends Y> exp1, Expression<? extends Y> exp2) {
|
||||
|
@ -1172,8 +1175,9 @@ public class CriteriaBuilderImpl implements CriteriaBuilder, Serializable {
|
|||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@SuppressWarnings({ "RedundantCast" })
|
||||
public <Y> Expression<Y> coalesce(Expression<? extends Y> exp1, Y exp2) {
|
||||
return coalesce( (Class<Y>)null, exp1, exp2 );
|
||||
return coalesce( (Class<Y>) null, exp1, exp2 );
|
||||
}
|
||||
|
||||
public <Y> Expression<Y> coalesce(Class<Y> type, Expression<? extends Y> exp1, Y exp2) {
|
||||
|
@ -1272,7 +1276,7 @@ public class CriteriaBuilderImpl implements CriteriaBuilder, Serializable {
|
|||
return size( ( (LiteralExpression<C>) exp ).getLiteral() );
|
||||
}
|
||||
else if ( CollectionExpression.class.isInstance(exp) ) {
|
||||
return new SizeOfCollectionExpression<C>(this, null);
|
||||
return new SizeOfCollectionExpression<C>(this, (CollectionExpression<C>) exp );
|
||||
}
|
||||
// TODO : what other specific types? any?
|
||||
throw new IllegalArgumentException("unknown collection expression type [" + exp.getClass().getName() + "]" );
|
||||
|
|
|
@ -38,6 +38,9 @@ import javax.persistence.LockModeType;
|
|||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.ParameterExpression;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.hibernate.ejb.HibernateEntityManagerImplementor;
|
||||
import org.hibernate.engine.SessionFactoryImplementor;
|
||||
import org.hibernate.type.Type;
|
||||
|
@ -54,6 +57,8 @@ import org.hibernate.util.StringHelper;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
public class CriteriaQueryCompiler {
|
||||
private static final Logger log = LoggerFactory.getLogger( CriteriaQueryCompiler.class );
|
||||
|
||||
public static interface ImplicitParameterBinding {
|
||||
public String getParameterName();
|
||||
public Class getJavaType();
|
||||
|
@ -72,7 +77,7 @@ public class CriteriaQueryCompiler {
|
|||
|
||||
public static interface RenderedCriteriaQuery {
|
||||
public String getQueryString();
|
||||
public List<ValueConverter.Conversion> getValueConversions();
|
||||
public List<ValueHandlerFactory.ValueHandler> getValueHandlers();
|
||||
public HibernateEntityManagerImplementor.Options.ResultMetadataValidator getResultMetadataValidator();
|
||||
}
|
||||
|
||||
|
@ -143,12 +148,14 @@ public class CriteriaQueryCompiler {
|
|||
|
||||
final RenderedCriteriaQuery renderedCriteriaQuery = criteriaQueryImpl.render( renderingContext );
|
||||
|
||||
log.debug( "Rendered criteria query -> {}", renderedCriteriaQuery.getQueryString() );
|
||||
|
||||
TypedQuery<T> jpaqlQuery = entityManager.createQuery(
|
||||
renderedCriteriaQuery.getQueryString(),
|
||||
criteriaQuery.getResultType(),
|
||||
new HibernateEntityManagerImplementor.Options() {
|
||||
public List<ValueConverter.Conversion> getConversions() {
|
||||
return renderedCriteriaQuery.getValueConversions();
|
||||
public List<ValueHandlerFactory.ValueHandler> getValueHandlers() {
|
||||
return renderedCriteriaQuery.getValueHandlers();
|
||||
}
|
||||
|
||||
public Map<String, Class> getNamedParameterExplicitTypes() {
|
||||
|
|
|
@ -355,11 +355,11 @@ public class CriteriaQueryImpl<T> extends AbstractNode implements CriteriaQuery<
|
|||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
public List<ValueConverter.Conversion> getValueConversions() {
|
||||
public List<ValueHandlerFactory.ValueHandler> getValueHandlers() {
|
||||
SelectionImplementor selection = (SelectionImplementor) queryStructure.getSelection();
|
||||
return selection == null
|
||||
? null
|
||||
: selection.getConversions();
|
||||
: selection.getValueHandlers();
|
||||
}
|
||||
|
||||
public HibernateEntityManagerImplementor.Options.ResultMetadataValidator getResultMetadataValidator() {
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.ejb.criteria;
|
||||
|
||||
import javax.persistence.criteria.Path;
|
||||
import javax.persistence.metamodel.Attribute;
|
||||
|
||||
/**
|
||||
* Implementation contract for the JPA {@link Path} interface.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface PathImplementor<X> extends ExpressionImplementor<X>, Path<X> {
|
||||
/**
|
||||
* Get the string representation of this path as a navigation from one of the
|
||||
* queries <tt>identification variables</tt>
|
||||
*
|
||||
* @return The path's identifier.
|
||||
*/
|
||||
public String getPathIdentifier();
|
||||
|
||||
/**
|
||||
* Retrieve reference to the attribute this path represents.
|
||||
*
|
||||
* @return The metamodel attribute.
|
||||
*/
|
||||
public Attribute<?, ?> getAttribute();
|
||||
}
|
|
@ -207,7 +207,7 @@ public class QueryStructure<T> {
|
|||
public void render(StringBuilder jpaqlQuery, CriteriaQueryCompiler.RenderingContext renderingContext) {
|
||||
jpaqlQuery.append( "select " );
|
||||
if ( isDistinct() ) {
|
||||
jpaqlQuery.append( " distinct " );
|
||||
jpaqlQuery.append( "distinct " );
|
||||
}
|
||||
if ( getSelection() == null ) {
|
||||
// we should have only a single root (query validation should have checked this...)
|
||||
|
|
|
@ -32,5 +32,5 @@ import javax.persistence.criteria.Selection;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface SelectionImplementor<X> extends TupleElementImplementor<X>, Selection<X> {
|
||||
public List<ValueConverter.Conversion> getConversions();
|
||||
public List<ValueHandlerFactory.ValueHandler> getValueHandlers();
|
||||
}
|
||||
|
|
|
@ -31,5 +31,5 @@ import javax.persistence.TupleElement;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface TupleElementImplementor<X> extends TupleElement<X> {
|
||||
public ValueConverter.Conversion<X> getConversion();
|
||||
public ValueHandlerFactory.ValueHandler<X> getValueHandler();
|
||||
}
|
||||
|
|
|
@ -27,16 +27,30 @@ import java.math.BigDecimal;
|
|||
import java.math.BigInteger;
|
||||
|
||||
/**
|
||||
* Helper for generically converting a values into another type.
|
||||
* Helper for generically dealing with literal values.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class ValueConverter {
|
||||
private ValueConverter() {
|
||||
public class ValueHandlerFactory {
|
||||
private ValueHandlerFactory() {
|
||||
}
|
||||
|
||||
public static interface Conversion<T> {
|
||||
public T apply(Object value);
|
||||
public static interface ValueHandler<T> {
|
||||
public T convert(Object value);
|
||||
public String render(T value);
|
||||
}
|
||||
|
||||
public static abstract class BaseValueHandler<T> implements ValueHandler<T> {
|
||||
public String render(T value) {
|
||||
return value.toString();
|
||||
}
|
||||
}
|
||||
|
||||
public static class NoOpValueHandler<T> extends BaseValueHandler<T> {
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
public T convert(Object value) {
|
||||
return (T) value;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isNumeric(Class type) {
|
||||
|
@ -44,15 +58,25 @@ public class ValueConverter {
|
|||
|| Byte.TYPE.equals( type )
|
||||
|| Short.TYPE.equals( type )
|
||||
|| Integer.TYPE.equals( type )
|
||||
|| Long.TYPE.isAssignableFrom( type )
|
||||
|| Long.TYPE.equals( type )
|
||||
|| Float.TYPE.equals( type )
|
||||
|| Double.TYPE.isAssignableFrom( type );
|
||||
|| Double.TYPE.equals( type );
|
||||
}
|
||||
|
||||
public static class ByteConversion implements Conversion<Byte> {
|
||||
public static final ByteConversion INSTANCE = new ByteConversion();
|
||||
public static boolean isNumeric(Object value) {
|
||||
return Number.class.isInstance( value )
|
||||
|| Byte.TYPE.isInstance( value )
|
||||
|| Short.TYPE.isInstance( value )
|
||||
|| Integer.TYPE.isInstance( value )
|
||||
|| Long.TYPE.isInstance( value )
|
||||
|| Float.TYPE.isInstance( value )
|
||||
|| Double.TYPE.isInstance( value );
|
||||
}
|
||||
|
||||
public static class ByteValueHandler extends BaseValueHandler<Byte> {
|
||||
public static final ByteValueHandler INSTANCE = new ByteValueHandler();
|
||||
@SuppressWarnings({ "UnnecessaryBoxing" })
|
||||
public Byte apply(Object value) {
|
||||
public Byte convert(Object value) {
|
||||
if ( value == null ) {
|
||||
return null;
|
||||
}
|
||||
|
@ -66,10 +90,10 @@ public class ValueConverter {
|
|||
}
|
||||
}
|
||||
|
||||
public static class ShortConversion implements Conversion<Short> {
|
||||
public static final ShortConversion INSTANCE = new ShortConversion();
|
||||
public static class ShortValueHandler extends BaseValueHandler<Short> {
|
||||
public static final ShortValueHandler INSTANCE = new ShortValueHandler();
|
||||
@SuppressWarnings({ "UnnecessaryBoxing" })
|
||||
public Short apply(Object value) {
|
||||
public Short convert(Object value) {
|
||||
if ( value == null ) {
|
||||
return null;
|
||||
}
|
||||
|
@ -83,10 +107,10 @@ public class ValueConverter {
|
|||
}
|
||||
}
|
||||
|
||||
public static class IntegerConversion implements Conversion<Integer> {
|
||||
public static final IntegerConversion INSTANCE = new IntegerConversion();
|
||||
public static class IntegerValueHandler extends BaseValueHandler<Integer> {
|
||||
public static final IntegerValueHandler INSTANCE = new IntegerValueHandler();
|
||||
@SuppressWarnings({ "UnnecessaryBoxing" })
|
||||
public Integer apply(Object value) {
|
||||
public Integer convert(Object value) {
|
||||
if ( value == null ) {
|
||||
return null;
|
||||
}
|
||||
|
@ -100,10 +124,10 @@ public class ValueConverter {
|
|||
}
|
||||
}
|
||||
|
||||
public static class LongConversion implements Conversion<Long> {
|
||||
public static final LongConversion INSTANCE = new LongConversion();
|
||||
public static class LongValueHandler extends BaseValueHandler<Long> {
|
||||
public static final LongValueHandler INSTANCE = new LongValueHandler();
|
||||
@SuppressWarnings({ "UnnecessaryBoxing" })
|
||||
public Long apply(Object value) {
|
||||
public Long convert(Object value) {
|
||||
if ( value == null ) {
|
||||
return null;
|
||||
}
|
||||
|
@ -115,12 +139,17 @@ public class ValueConverter {
|
|||
}
|
||||
throw unknownConversion( value, Long.class );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String render(Long value) {
|
||||
return value.toString() + 'L';
|
||||
}
|
||||
}
|
||||
|
||||
public static class FloatConversion implements Conversion<Float> {
|
||||
public static final FloatConversion INSTANCE = new FloatConversion();
|
||||
public static class FloatValueHandler extends BaseValueHandler<Float> {
|
||||
public static final FloatValueHandler INSTANCE = new FloatValueHandler();
|
||||
@SuppressWarnings({ "UnnecessaryBoxing" })
|
||||
public Float apply(Object value) {
|
||||
public Float convert(Object value) {
|
||||
if ( value == null ) {
|
||||
return null;
|
||||
}
|
||||
|
@ -132,12 +161,17 @@ public class ValueConverter {
|
|||
}
|
||||
throw unknownConversion( value, Float.class );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String render(Float value) {
|
||||
return value.toString() + 'F';
|
||||
}
|
||||
}
|
||||
|
||||
public static class DoubleConversion implements Conversion<Double> {
|
||||
public static final DoubleConversion INSTANCE = new DoubleConversion();
|
||||
public static class DoubleValueHandler extends BaseValueHandler<Double> {
|
||||
public static final DoubleValueHandler INSTANCE = new DoubleValueHandler();
|
||||
@SuppressWarnings({ "UnnecessaryBoxing" })
|
||||
public Double apply(Object value) {
|
||||
public Double convert(Object value) {
|
||||
if ( value == null ) {
|
||||
return null;
|
||||
}
|
||||
|
@ -149,11 +183,16 @@ public class ValueConverter {
|
|||
}
|
||||
throw unknownConversion( value, Double.class );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String render(Double value) {
|
||||
return value.toString() + 'D';
|
||||
}
|
||||
}
|
||||
|
||||
public static class BigIntegerConversion implements Conversion<BigInteger> {
|
||||
public static final BigIntegerConversion INSTANCE = new BigIntegerConversion();
|
||||
public BigInteger apply(Object value) {
|
||||
public static class BigIntegerValueHandler extends BaseValueHandler<BigInteger> {
|
||||
public static final BigIntegerValueHandler INSTANCE = new BigIntegerValueHandler();
|
||||
public BigInteger convert(Object value) {
|
||||
if ( value == null ) {
|
||||
return null;
|
||||
}
|
||||
|
@ -167,9 +206,9 @@ public class ValueConverter {
|
|||
}
|
||||
}
|
||||
|
||||
public static class BigDecimalConversion implements Conversion<BigDecimal> {
|
||||
public static final BigDecimalConversion INSTANCE = new BigDecimalConversion();
|
||||
public BigDecimal apply(Object value) {
|
||||
public static class BigDecimalValueHandler extends BaseValueHandler<BigDecimal> {
|
||||
public static final BigDecimalValueHandler INSTANCE = new BigDecimalValueHandler();
|
||||
public BigDecimal convert(Object value) {
|
||||
if ( value == null ) {
|
||||
return null;
|
||||
}
|
||||
|
@ -186,9 +225,9 @@ public class ValueConverter {
|
|||
}
|
||||
}
|
||||
|
||||
public static class StringConversion implements Conversion<String> {
|
||||
public static final StringConversion INSTANCE = new StringConversion();
|
||||
public String apply(Object value) {
|
||||
public static class StringValueHandler extends BaseValueHandler<String> {
|
||||
public static final StringValueHandler INSTANCE = new StringValueHandler();
|
||||
public String convert(Object value) {
|
||||
return value == null ? null : value.toString();
|
||||
}
|
||||
}
|
||||
|
@ -220,15 +259,15 @@ public class ValueConverter {
|
|||
return (T) value;
|
||||
}
|
||||
|
||||
Conversion<T> conversion = determineAppropriateConversion( targetType );
|
||||
if ( conversion == null ) {
|
||||
ValueHandler<T> valueHandler = determineAppropriateHandler( targetType );
|
||||
if ( valueHandler == null ) {
|
||||
throw unknownConversion( value, targetType );
|
||||
}
|
||||
return conversion.apply( value );
|
||||
return valueHandler.convert( value );
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the appropriate {@link Conversion} strategy for converting a value
|
||||
* Determine the appropriate {@link ValueHandlerFactory.ValueHandler} strategy for converting a value
|
||||
* to the given target type
|
||||
*
|
||||
* @param targetType The target type (to which we want to convert values).
|
||||
|
@ -236,33 +275,33 @@ public class ValueConverter {
|
|||
* @return The conversion
|
||||
*/
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
public static <T> Conversion<T> determineAppropriateConversion(Class<T> targetType) {
|
||||
public static <T> ValueHandler<T> determineAppropriateHandler(Class<T> targetType) {
|
||||
if ( String.class.equals( targetType ) ) {
|
||||
return (Conversion<T>) StringConversion.INSTANCE;
|
||||
return (ValueHandler<T>) StringValueHandler.INSTANCE;
|
||||
}
|
||||
if ( Byte.class.equals( targetType ) || Byte.TYPE.equals( targetType ) ) {
|
||||
return (Conversion<T>) ByteConversion.INSTANCE;
|
||||
return (ValueHandler<T>) ByteValueHandler.INSTANCE;
|
||||
}
|
||||
if ( Short.class.equals( targetType ) || Short.TYPE.equals( targetType ) ) {
|
||||
return (Conversion<T>) ShortConversion.INSTANCE;
|
||||
return (ValueHandler<T>) ShortValueHandler.INSTANCE;
|
||||
}
|
||||
if ( Integer.class.equals( targetType ) || Integer.TYPE.equals( targetType ) ) {
|
||||
return (Conversion<T>) IntegerConversion.INSTANCE;
|
||||
return (ValueHandler<T>) IntegerValueHandler.INSTANCE;
|
||||
}
|
||||
if ( Long.class.equals( targetType ) || Long.TYPE.equals( targetType ) ) {
|
||||
return (Conversion<T>) LongConversion.INSTANCE;
|
||||
return (ValueHandler<T>) LongValueHandler.INSTANCE;
|
||||
}
|
||||
if ( Float.class.equals( targetType ) || Float.TYPE.equals( targetType ) ) {
|
||||
return (Conversion<T>) FloatConversion.INSTANCE;
|
||||
return (ValueHandler<T>) FloatValueHandler.INSTANCE;
|
||||
}
|
||||
if ( Double.class.equals( targetType ) || Double.TYPE.equals( targetType ) ) {
|
||||
return (Conversion<T>) DoubleConversion.INSTANCE;
|
||||
return (ValueHandler<T>) DoubleValueHandler.INSTANCE;
|
||||
}
|
||||
if ( BigInteger.class.equals( targetType ) ) {
|
||||
return (Conversion<T>) BigIntegerConversion.INSTANCE;
|
||||
return (ValueHandler<T>) BigIntegerValueHandler.INSTANCE;
|
||||
}
|
||||
if ( BigDecimal.class.equals( targetType ) ) {
|
||||
return (Conversion<T>) BigDecimalConversion.INSTANCE;
|
||||
return (ValueHandler<T>) BigDecimalValueHandler.INSTANCE;
|
||||
}
|
||||
return null;
|
||||
}
|
|
@ -26,7 +26,7 @@ package org.hibernate.ejb.criteria.expression;
|
|||
import org.hibernate.ejb.criteria.AbstractNode;
|
||||
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
|
||||
import org.hibernate.ejb.criteria.TupleElementImplementor;
|
||||
import org.hibernate.ejb.criteria.ValueConverter;
|
||||
import org.hibernate.ejb.criteria.ValueHandlerFactory;
|
||||
|
||||
/**
|
||||
* TODO : javadoc
|
||||
|
@ -39,7 +39,7 @@ public abstract class AbstractTupleElement<X>
|
|||
private final Class originalJavaType;
|
||||
private Class<X> javaType;
|
||||
private String alias;
|
||||
private ValueConverter.Conversion<X> conversion;
|
||||
private ValueHandlerFactory.ValueHandler<X> valueHandler;
|
||||
|
||||
protected AbstractTupleElement(CriteriaBuilderImpl criteriaBuilder, Class<X> javaType) {
|
||||
super( criteriaBuilder );
|
||||
|
@ -57,21 +57,21 @@ public abstract class AbstractTupleElement<X>
|
|||
@SuppressWarnings({ "unchecked" })
|
||||
protected void resetJavaType(Class targetType) {
|
||||
this.javaType = targetType;
|
||||
// this.conversion = javaType.equals( originalJavaType )
|
||||
// this.valueHandler = javaType.equals( originalJavaType )
|
||||
// ? null
|
||||
// : ValueConverter.determineAppropriateConversion( javaType );
|
||||
this.conversion = ValueConverter.determineAppropriateConversion( javaType );
|
||||
// : ValueHandlerFactory.determineAppropriateHandler( javaType );
|
||||
this.valueHandler = ValueHandlerFactory.determineAppropriateHandler( javaType );
|
||||
}
|
||||
|
||||
protected void forceConversion(ValueConverter.Conversion<X> conversion) {
|
||||
this.conversion = conversion;
|
||||
protected void forceConversion(ValueHandlerFactory.ValueHandler<X> valueHandler) {
|
||||
this.valueHandler = valueHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public ValueConverter.Conversion<X> getConversion() {
|
||||
return conversion;
|
||||
public ValueHandlerFactory.ValueHandler<X> getValueHandler() {
|
||||
return valueHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -67,7 +67,8 @@ public class BinaryArithmeticOperation<N extends Number>
|
|||
},
|
||||
MOD {
|
||||
String apply(String lhs, String rhs) {
|
||||
return lhs + " % " + rhs;
|
||||
// return lhs + " % " + rhs;
|
||||
return "mod(" + lhs + "," + rhs + ")";
|
||||
}
|
||||
};
|
||||
abstract String apply(String lhs, String rhs);
|
||||
|
|
|
@ -34,7 +34,7 @@ import org.hibernate.ejb.criteria.ParameterRegistry;
|
|||
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
|
||||
import org.hibernate.ejb.criteria.Renderable;
|
||||
import org.hibernate.ejb.criteria.TupleElementImplementor;
|
||||
import org.hibernate.ejb.criteria.ValueConverter;
|
||||
import org.hibernate.ejb.criteria.ValueHandlerFactory;
|
||||
|
||||
/**
|
||||
* The Hibernate implementation of the JPA {@link CompoundSelection}
|
||||
|
@ -66,18 +66,18 @@ public class CompoundSelectionImpl<X> extends SelectionImpl<X> implements Compou
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<ValueConverter.Conversion> getConversions() {
|
||||
public List<ValueHandlerFactory.ValueHandler> getValueHandlers() {
|
||||
if ( isConstructor ) {
|
||||
return null;
|
||||
}
|
||||
boolean foundConversions = false;
|
||||
ArrayList<ValueConverter.Conversion> conversions = new ArrayList<ValueConverter.Conversion>();
|
||||
boolean foundHandlers = false;
|
||||
ArrayList<ValueHandlerFactory.ValueHandler> valueHandlers = new ArrayList<ValueHandlerFactory.ValueHandler>();
|
||||
for ( Selection selection : getCompoundSelectionItems() ) {
|
||||
ValueConverter.Conversion conversion = ( (TupleElementImplementor) selection ).getConversion();
|
||||
conversions.add( conversion );
|
||||
foundConversions = foundConversions || conversion != null;
|
||||
ValueHandlerFactory.ValueHandler valueHandler = ( (TupleElementImplementor) selection ).getValueHandler();
|
||||
valueHandlers.add( valueHandler );
|
||||
foundHandlers = foundHandlers || valueHandler != null;
|
||||
}
|
||||
return foundConversions ? null : conversions;
|
||||
return foundHandlers ? null : valueHandlers;
|
||||
}
|
||||
|
||||
public void registerParameters(ParameterRegistry registry) {
|
||||
|
|
|
@ -25,7 +25,7 @@ package org.hibernate.ejb.criteria.expression;
|
|||
|
||||
import javax.persistence.TypedQuery;
|
||||
|
||||
import org.hibernate.ejb.criteria.ValueConverter;
|
||||
import org.hibernate.ejb.criteria.ValueHandlerFactory;
|
||||
import org.hibernate.ejb.criteria.ParameterRegistry;
|
||||
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
|
||||
import org.hibernate.ejb.criteria.CriteriaQueryCompiler;
|
||||
|
@ -61,7 +61,13 @@ public class LiteralExpression<T> extends ExpressionImpl<T> {
|
|||
// nothing to do
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
public String render(CriteriaQueryCompiler.RenderingContext renderingContext) {
|
||||
if ( ValueHandlerFactory.isNumeric( literal ) ) {
|
||||
return ValueHandlerFactory.determineAppropriateHandler( (Class) literal.getClass() ).render( literal );
|
||||
}
|
||||
|
||||
// else...
|
||||
final String parameterName = renderingContext.generateParameterName();
|
||||
renderingContext.registerImplicitParameterBinding(
|
||||
new CriteriaQueryCompiler.ImplicitParameterBinding() {
|
||||
|
@ -89,14 +95,14 @@ public class LiteralExpression<T> extends ExpressionImpl<T> {
|
|||
@SuppressWarnings({ "unchecked" })
|
||||
protected void resetJavaType(Class targetType) {
|
||||
super.resetJavaType( targetType );
|
||||
ValueConverter.Conversion conversion = getConversion();
|
||||
if ( conversion == null ) {
|
||||
conversion = ValueConverter.determineAppropriateConversion( targetType );
|
||||
forceConversion( conversion );
|
||||
ValueHandlerFactory.ValueHandler valueHandler = getValueHandler();
|
||||
if ( valueHandler == null ) {
|
||||
valueHandler = ValueHandlerFactory.determineAppropriateHandler( targetType );
|
||||
forceConversion( valueHandler );
|
||||
}
|
||||
|
||||
if ( conversion != null ) {
|
||||
literal = conversion.apply( literal );
|
||||
if ( valueHandler != null ) {
|
||||
literal = valueHandler.convert( literal );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ import javax.persistence.criteria.Selection;
|
|||
import org.hibernate.ejb.criteria.ParameterContainer;
|
||||
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
|
||||
import org.hibernate.ejb.criteria.SelectionImplementor;
|
||||
import org.hibernate.ejb.criteria.ValueConverter;
|
||||
import org.hibernate.ejb.criteria.ValueHandlerFactory;
|
||||
|
||||
/**
|
||||
* The Hibernate implementation of the JPA {@link Selection}
|
||||
|
@ -54,13 +54,13 @@ public abstract class SelectionImpl<X>
|
|||
return false;
|
||||
}
|
||||
|
||||
public List<ValueConverter.Conversion> getConversions() {
|
||||
return getConversion() == null
|
||||
public List<ValueHandlerFactory.ValueHandler> getValueHandlers() {
|
||||
return getValueHandler() == null
|
||||
? null
|
||||
: Collections.singletonList( (ValueConverter.Conversion) getConversion() );
|
||||
: Collections.singletonList( (ValueHandlerFactory.ValueHandler) getValueHandler() );
|
||||
}
|
||||
|
||||
public List<Selection<?>> getCompoundSelectionItems() {
|
||||
throw new IllegalStateException( "Not a compund selection" );
|
||||
throw new IllegalStateException( "Not a compound selection" );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,11 +50,11 @@ public class SizeOfCollectionExpression<C extends Collection>
|
|||
}
|
||||
|
||||
public void registerParameters(ParameterRegistry registry) {
|
||||
// nothign to do
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
public String render(CriteriaQueryCompiler.RenderingContext renderingContext) {
|
||||
return "size of " + getCollectionExpression().render( renderingContext );
|
||||
return "size(" + getCollectionExpression().render( renderingContext ) + ")";
|
||||
}
|
||||
|
||||
public String renderProjection(CriteriaQueryCompiler.RenderingContext renderingContext) {
|
||||
|
|
|
@ -25,6 +25,7 @@ package org.hibernate.ejb.criteria.expression.function;
|
|||
|
||||
import javax.persistence.criteria.Expression;
|
||||
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
|
||||
import org.hibernate.ejb.criteria.CriteriaQueryCompiler;
|
||||
import org.hibernate.ejb.criteria.expression.LiteralExpression;
|
||||
|
||||
/**
|
||||
|
@ -87,6 +88,14 @@ public class AggregationFunction<T> extends ParameterizedFunctionExpression<T> {
|
|||
this.distinct = distinct;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderArguments(StringBuilder buffer, CriteriaQueryCompiler.RenderingContext renderingContext) {
|
||||
if ( isDistinct() ) {
|
||||
buffer.append( "distinct " );
|
||||
}
|
||||
super.renderArguments( buffer, renderingContext );
|
||||
}
|
||||
|
||||
public boolean isDistinct() {
|
||||
return distinct;
|
||||
}
|
||||
|
|
|
@ -91,12 +91,15 @@ public class ParameterizedFunctionExpression<X>
|
|||
@Override
|
||||
public String render(CriteriaQueryCompiler.RenderingContext renderingContext) {
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
buffer.append( getFunctionName() )
|
||||
.append( '(' );
|
||||
for ( Expression argument : argumentExpressions ) {
|
||||
buffer.append( ( (Renderable) argument ).render( renderingContext ) );
|
||||
}
|
||||
buffer.append( getFunctionName() ).append( '(' );
|
||||
renderArguments( buffer, renderingContext );
|
||||
buffer.append( ')' );
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
protected void renderArguments(StringBuilder buffer, CriteriaQueryCompiler.RenderingContext renderingContext) {
|
||||
for ( Expression argument : argumentExpressions ) {
|
||||
buffer.append( ( (Renderable) argument ).render( renderingContext ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -83,8 +83,9 @@ public class BetweenPredicate<Y> extends AbstractSimplePredicate {
|
|||
}
|
||||
|
||||
public String render(CriteriaQueryCompiler.RenderingContext renderingContext) {
|
||||
final String operator = isNegated() ? " not between " : " between ";
|
||||
return ( (Renderable) getExpression() ).render( renderingContext )
|
||||
+ " between "
|
||||
+ operator
|
||||
+ ( (Renderable) getLowerBound() ).render( renderingContext )
|
||||
+ " and "
|
||||
+ ( (Renderable) getUpperBound() ).render( renderingContext );
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.ejb.criteria.predicate;
|
||||
|
||||
import javax.persistence.criteria.Expression;
|
||||
|
||||
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
|
||||
import org.hibernate.ejb.criteria.CriteriaQueryCompiler;
|
||||
import org.hibernate.ejb.criteria.ParameterRegistry;
|
||||
import org.hibernate.ejb.criteria.Renderable;
|
||||
|
||||
/**
|
||||
* TODO : javadoc
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class BooleanAssertionPredicate extends AbstractSimplePredicate {
|
||||
private final Expression<Boolean> expression;
|
||||
private final Boolean assertedValue;
|
||||
|
||||
public BooleanAssertionPredicate(
|
||||
CriteriaBuilderImpl criteriaBuilder,
|
||||
Expression<Boolean> expression,
|
||||
Boolean assertedValue) {
|
||||
super( criteriaBuilder );
|
||||
this.expression = expression;
|
||||
this.assertedValue = assertedValue;
|
||||
}
|
||||
|
||||
public Expression<Boolean> getExpression() {
|
||||
return expression;
|
||||
}
|
||||
|
||||
public Boolean getAssertedValue() {
|
||||
return assertedValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void registerParameters(ParameterRegistry registry) {
|
||||
Helper.possibleParameter( expression, registry );
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public String render(CriteriaQueryCompiler.RenderingContext renderingContext) {
|
||||
final String operator = isNegated() ? " = " : " <> ";
|
||||
final String assertionLiteral = assertedValue ? "true" : "false";
|
||||
|
||||
return ( (Renderable) expression ).render( renderingContext )
|
||||
+ operator
|
||||
+ assertionLiteral;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public String renderProjection(CriteriaQueryCompiler.RenderingContext renderingContext) {
|
||||
return render( renderingContext );
|
||||
}
|
||||
|
||||
}
|
|
@ -25,7 +25,7 @@ package org.hibernate.ejb.criteria.predicate;
|
|||
|
||||
import javax.persistence.criteria.Expression;
|
||||
|
||||
import org.hibernate.ejb.criteria.ValueConverter;
|
||||
import org.hibernate.ejb.criteria.ValueHandlerFactory;
|
||||
import org.hibernate.ejb.criteria.ParameterRegistry;
|
||||
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
|
||||
import org.hibernate.ejb.criteria.CriteriaQueryCompiler;
|
||||
|
@ -63,10 +63,10 @@ public class ComparisonPredicate extends AbstractSimplePredicate implements Bina
|
|||
super( criteriaBuilder );
|
||||
this.comparisonOperator = comparisonOperator;
|
||||
this.leftHandSide = leftHandSide;
|
||||
if ( ValueConverter.isNumeric( leftHandSide.getJavaType() ) ) {
|
||||
if ( ValueHandlerFactory.isNumeric( leftHandSide.getJavaType() ) ) {
|
||||
this.rightHandSide = new LiteralExpression(
|
||||
criteriaBuilder,
|
||||
ValueConverter.convert( rightHandSide, (Class<Number>) leftHandSide.getJavaType() )
|
||||
ValueHandlerFactory.convert( rightHandSide, (Class<Number>) leftHandSide.getJavaType() )
|
||||
);
|
||||
}
|
||||
else {
|
||||
|
@ -84,7 +84,7 @@ public class ComparisonPredicate extends AbstractSimplePredicate implements Bina
|
|||
this.leftHandSide = leftHandSide;
|
||||
this.rightHandSide = new LiteralExpression<N>(
|
||||
criteriaBuilder,
|
||||
ValueConverter.convert( rightHandSide, leftHandSide.getJavaType() )
|
||||
ValueHandlerFactory.convert( rightHandSide, leftHandSide.getJavaType() )
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ import org.hibernate.ejb.criteria.CriteriaQueryCompiler;
|
|||
import org.hibernate.ejb.criteria.Renderable;
|
||||
|
||||
/**
|
||||
* A compound {@link Predicate predicate} is a grouping of other {@link Predicate predicates} in order to apply
|
||||
* A compound {@link Predicate predicate} is a grouping of other {@link Predicate predicates} in order to convert
|
||||
* either a conjunction (logical AND) or a disjunction (logical OR).
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
|
|
|
@ -34,6 +34,7 @@ import org.hibernate.ejb.criteria.ParameterRegistry;
|
|||
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
|
||||
import org.hibernate.ejb.criteria.CriteriaQueryCompiler;
|
||||
import org.hibernate.ejb.criteria.Renderable;
|
||||
import org.hibernate.ejb.criteria.ValueHandlerFactory;
|
||||
import org.hibernate.ejb.criteria.expression.LiteralExpression;
|
||||
|
||||
/**
|
||||
|
@ -114,10 +115,14 @@ public class InPredicate<T> extends AbstractSimplePredicate implements CriteriaB
|
|||
Collection<T> values) {
|
||||
super( criteriaBuilder );
|
||||
this.expression = expression;
|
||||
// TODO : size this?
|
||||
this.values = new ArrayList<Expression<? extends T>>();
|
||||
this.values = new ArrayList<Expression<? extends T>>( values.size() );
|
||||
ValueHandlerFactory.ValueHandler<? extends T> valueHandler = ValueHandlerFactory.isNumeric( expression.getJavaType() )
|
||||
? ValueHandlerFactory.determineAppropriateHandler( (Class<? extends T>) expression.getJavaType() )
|
||||
: new ValueHandlerFactory.NoOpValueHandler<T>();
|
||||
for ( T value : values ) {
|
||||
this.values.add( new LiteralExpression<T>( criteriaBuilder, value ) );
|
||||
this.values.add(
|
||||
new LiteralExpression<T>( criteriaBuilder, valueHandler.convert( value ) )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -151,10 +156,17 @@ public class InPredicate<T> extends AbstractSimplePredicate implements CriteriaB
|
|||
}
|
||||
|
||||
public String render(CriteriaQueryCompiler.RenderingContext renderingContext) {
|
||||
StringBuilder buffer = new StringBuilder( "in" );
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
|
||||
// subquery expressions are already wrapped in parenthesis, so we only
|
||||
// need to render the parens here if the values represent an explicit value list
|
||||
buffer.append( ( (Renderable) getExpression() ).render( renderingContext ) );
|
||||
|
||||
if ( isNegated() ) {
|
||||
buffer.append( " not" );
|
||||
}
|
||||
buffer.append( " in " );
|
||||
|
||||
// subquery expressions are already wrapped in parenthesis, so we only need to
|
||||
// render the parenthesis here if the values represent an explicit value list
|
||||
boolean isInSubqueryPredicate = getValues().size() == 1
|
||||
&& Subquery.class.isInstance( getValues().get( 0 ) );
|
||||
if ( isInSubqueryPredicate ) {
|
||||
|
|
|
@ -57,7 +57,8 @@ public class IsEmptyPredicate<C extends Collection>
|
|||
}
|
||||
|
||||
public String render(CriteriaQueryCompiler.RenderingContext renderingContext) {
|
||||
return getOperand().render( renderingContext ) + " is empty";
|
||||
final String operator = isNegated() ? " is not empty" : " is empty";
|
||||
return getOperand().render( renderingContext ) + operator;
|
||||
}
|
||||
|
||||
public String renderProjection(CriteriaQueryCompiler.RenderingContext renderingContext) {
|
||||
|
|
|
@ -123,15 +123,16 @@ public class LikePredicate extends AbstractSimplePredicate {
|
|||
}
|
||||
|
||||
public String render(CriteriaQueryCompiler.RenderingContext renderingContext) {
|
||||
StringBuilder likeExpr = new StringBuilder();
|
||||
likeExpr.append( ( (Renderable) getMatchExpression() ).render( renderingContext ) )
|
||||
.append( " like " )
|
||||
final String operator = isNegated() ? " not like " : " like ";
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
buffer.append( ( (Renderable) getMatchExpression() ).render( renderingContext ) )
|
||||
.append( operator )
|
||||
.append( ( (Renderable) getPattern() ).render( renderingContext ) );
|
||||
if ( escapeCharacter != null ) {
|
||||
likeExpr.append( " escape " )
|
||||
buffer.append( " escape " )
|
||||
.append( ( (Renderable) getEscapeCharacter() ).render( renderingContext ) );
|
||||
}
|
||||
return likeExpr.toString();
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
public String renderProjection(CriteriaQueryCompiler.RenderingContext renderingContext) {
|
||||
|
|
|
@ -28,6 +28,7 @@ import javax.persistence.criteria.Expression;
|
|||
import org.hibernate.ejb.criteria.ParameterRegistry;
|
||||
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
|
||||
import org.hibernate.ejb.criteria.CriteriaQueryCompiler;
|
||||
import org.hibernate.ejb.criteria.Renderable;
|
||||
import org.hibernate.ejb.criteria.expression.CollectionExpression;
|
||||
import org.hibernate.ejb.criteria.expression.LiteralExpression;
|
||||
|
||||
|
@ -76,7 +77,8 @@ public class MemberOfPredicate<E, C extends Collection<E>>
|
|||
}
|
||||
|
||||
public String render(CriteriaQueryCompiler.RenderingContext renderingContext) {
|
||||
return ( isNegated() ? "not " : "" ) + "member of "
|
||||
return ( (Renderable) elementExpression ).render( renderingContext )
|
||||
+ ( isNegated() ? " not" : "" ) + " member of "
|
||||
+ collectionExpression.render( renderingContext );
|
||||
}
|
||||
|
||||
|
|
|
@ -23,21 +23,31 @@
|
|||
*/
|
||||
package org.hibernate.ejb.criteria;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutput;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
import javax.persistence.criteria.Root;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.Join;
|
||||
import javax.persistence.criteria.Root;
|
||||
|
||||
import org.hibernate.ejb.metamodel.Address;
|
||||
import org.hibernate.ejb.metamodel.Alias;
|
||||
import org.hibernate.ejb.metamodel.Country;
|
||||
import org.hibernate.ejb.metamodel.CreditCard;
|
||||
import org.hibernate.ejb.metamodel.Customer;
|
||||
import org.hibernate.ejb.metamodel.Info;
|
||||
import org.hibernate.ejb.metamodel.LineItem;
|
||||
import org.hibernate.ejb.metamodel.Order;
|
||||
import org.hibernate.ejb.metamodel.Phone;
|
||||
import org.hibernate.ejb.metamodel.Product;
|
||||
import org.hibernate.ejb.metamodel.ShelfLife;
|
||||
import org.hibernate.ejb.metamodel.Spouse;
|
||||
import org.hibernate.ejb.test.TestCase;
|
||||
import org.hibernate.ejb.test.callbacks.VideoSystem;
|
||||
import org.hibernate.ejb.test.callbacks.Television;
|
||||
import org.hibernate.ejb.test.callbacks.RemoteControl;
|
||||
import org.hibernate.ejb.test.callbacks.Television;
|
||||
import org.hibernate.ejb.test.callbacks.VideoSystem;
|
||||
import org.hibernate.ejb.test.inheritance.Fruit;
|
||||
import org.hibernate.ejb.test.inheritance.Strawberry;
|
||||
|
||||
|
@ -50,9 +60,17 @@ public class CriteriaCompilingTest extends TestCase {
|
|||
public Class[] getAnnotatedClasses() {
|
||||
return new Class[] {
|
||||
Customer.class,
|
||||
Item.class,
|
||||
Alias.class,
|
||||
Phone.class,
|
||||
Address.class,
|
||||
Country.class,
|
||||
CreditCard.class,
|
||||
Info.class,
|
||||
Spouse.class,
|
||||
LineItem.class,
|
||||
Order.class,
|
||||
Product.class,
|
||||
ShelfLife.class,
|
||||
// @Inheritance
|
||||
Fruit.class,
|
||||
Strawberry.class,
|
||||
|
@ -112,7 +130,6 @@ public class CriteriaCompilingTest extends TestCase {
|
|||
em.close();
|
||||
}
|
||||
|
||||
//FIXME uncomment the serialization line and enjoy the test failing
|
||||
public void testSerialization() {
|
||||
EntityManager em = getOrCreateEntityManager();
|
||||
em.getTransaction().begin();
|
||||
|
@ -122,8 +139,8 @@ public class CriteriaCompilingTest extends TestCase {
|
|||
root.fetch( "lineItems" );
|
||||
criteria.select( root );
|
||||
|
||||
//FIXME uncomment the serialization line and enjoy the test failing
|
||||
//criteria = serializeDdeserialize( criteria );
|
||||
// TODO uncomment the serialization line and enjoy the test failing
|
||||
// criteria = serializeDeserialize( criteria );
|
||||
|
||||
em.createQuery( criteria ).getResultList();
|
||||
|
||||
|
@ -131,7 +148,7 @@ public class CriteriaCompilingTest extends TestCase {
|
|||
em.close();
|
||||
}
|
||||
|
||||
private <T> T serializeDdeserialize(T object) {
|
||||
private <T> T serializeDeserialize(T object) {
|
||||
T serializedObject = null;
|
||||
try {
|
||||
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
||||
|
|
|
@ -1,79 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
|
||||
* third-party contributors as indicated by either @author tags or express
|
||||
* copyright attribution statements applied by the authors. All
|
||||
* third-party contributions are distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.ejb.criteria;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.OneToMany;
|
||||
|
||||
/**
|
||||
* TODO : javadoc
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@Entity
|
||||
public class Customer {
|
||||
private Long id;
|
||||
private String name;
|
||||
private int status;
|
||||
private Set<Order> orders = new HashSet<Order>();
|
||||
|
||||
@Id
|
||||
@GeneratedValue
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public int getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(int status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@OneToMany( mappedBy = "customer" )
|
||||
public Set<Order> getOrders() {
|
||||
return orders;
|
||||
}
|
||||
|
||||
void setOrders(Set<Order> orders) {
|
||||
this.orders = orders;
|
||||
}
|
||||
}
|
|
@ -1,78 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
|
||||
* third-party contributors as indicated by either @author tags or express
|
||||
* copyright attribution statements applied by the authors. All
|
||||
* third-party contributions are distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.ejb.criteria;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.ManyToOne;
|
||||
|
||||
/**
|
||||
* TODO : javadoc
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@Entity
|
||||
public class Item {
|
||||
private Long id;
|
||||
private Order order;
|
||||
private Product product;
|
||||
private long quantity;
|
||||
|
||||
@Id
|
||||
@GeneratedValue
|
||||
Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@ManyToOne
|
||||
public Order getOrder() {
|
||||
return order;
|
||||
}
|
||||
|
||||
public void setOrder(Order order) {
|
||||
this.order = order;
|
||||
}
|
||||
|
||||
@ManyToOne
|
||||
public Product getProduct() {
|
||||
return product;
|
||||
}
|
||||
|
||||
public void setProduct(Product product) {
|
||||
this.product = product;
|
||||
}
|
||||
|
||||
public long getQuantity() {
|
||||
return quantity;
|
||||
}
|
||||
|
||||
public void setQuantity(long quantity) {
|
||||
this.quantity = quantity;
|
||||
}
|
||||
}
|
|
@ -1,84 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
|
||||
* third-party contributors as indicated by either @author tags or express
|
||||
* copyright attribution statements applied by the authors. All
|
||||
* third-party contributions are distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.ejb.criteria;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.Table;
|
||||
|
||||
/**
|
||||
* TODO : javadoc
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@Entity
|
||||
@Table( name="t_order" )
|
||||
public class Order {
|
||||
private Long id;
|
||||
private Customer customer;
|
||||
private Date date;
|
||||
private Set<Item> lineItems = new HashSet<Item>();
|
||||
|
||||
@Id
|
||||
@GeneratedValue
|
||||
Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@ManyToOne
|
||||
public Customer getCustomer() {
|
||||
return customer;
|
||||
}
|
||||
|
||||
public void setCustomer(Customer customer) {
|
||||
this.customer = customer;
|
||||
}
|
||||
|
||||
public Date getDate() {
|
||||
return date;
|
||||
}
|
||||
|
||||
public void setDate(Date date) {
|
||||
this.date = date;
|
||||
}
|
||||
|
||||
@OneToMany( mappedBy = "order" )
|
||||
public Set<Item> getLineItems() {
|
||||
return lineItems;
|
||||
}
|
||||
|
||||
void setLineItems(Set<Item> lineItems) {
|
||||
this.lineItems = lineItems;
|
||||
}
|
||||
}
|
|
@ -1,80 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
|
||||
* third-party contributors as indicated by either @author tags or express
|
||||
* copyright attribution statements applied by the authors. All
|
||||
* third-party contributions are distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.ejb.criteria;
|
||||
|
||||
/**
|
||||
* TODO : javadoc
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@javax.persistence.Entity
|
||||
public class Product {
|
||||
private Long id;
|
||||
private String name;
|
||||
private String manufacturer;
|
||||
private String model;
|
||||
private String productType;
|
||||
|
||||
@javax.persistence.Id
|
||||
@javax.persistence.GeneratedValue
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getManufacturer() {
|
||||
return manufacturer;
|
||||
}
|
||||
|
||||
public void setManufacturer(String manufacturer) {
|
||||
this.manufacturer = manufacturer;
|
||||
}
|
||||
|
||||
public String getModel() {
|
||||
return model;
|
||||
}
|
||||
|
||||
public void setModel(String model) {
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
public String getProductType() {
|
||||
return productType;
|
||||
}
|
||||
|
||||
public void setProductType(String productType) {
|
||||
this.productType = productType;
|
||||
}
|
||||
}
|
|
@ -23,12 +23,15 @@
|
|||
*/
|
||||
package org.hibernate.ejb.criteria;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.TypedQuery;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.Expression;
|
||||
import javax.persistence.criteria.Root;
|
||||
import javax.persistence.metamodel.EntityType;
|
||||
import javax.persistence.metamodel.PluralAttribute;
|
||||
|
||||
import org.hibernate.ejb.criteria.predicate.ComparisonPredicate;
|
||||
import org.hibernate.ejb.metamodel.Address;
|
||||
|
@ -36,6 +39,7 @@ import org.hibernate.ejb.metamodel.Alias;
|
|||
import org.hibernate.ejb.metamodel.Country;
|
||||
import org.hibernate.ejb.metamodel.CreditCard;
|
||||
import org.hibernate.ejb.metamodel.Customer;
|
||||
import org.hibernate.ejb.metamodel.Customer_;
|
||||
import org.hibernate.ejb.metamodel.Info;
|
||||
import org.hibernate.ejb.metamodel.LineItem;
|
||||
import org.hibernate.ejb.metamodel.Order;
|
||||
|
|
Loading…
Reference in New Issue