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:
Steve Ebersole 2010-01-04 18:16:42 +00:00
parent ef1cb9f066
commit 33b7b6c803
32 changed files with 392 additions and 473 deletions

View File

@ -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;
}

View File

@ -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

View File

@ -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() + "]" );

View File

@ -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() {

View File

@ -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() {

View File

@ -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();
}

View File

@ -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...)

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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;
}

View File

@ -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;
}
/**

View File

@ -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);

View File

@ -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) {

View File

@ -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 );
}
}
}

View File

@ -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" );
}
}

View File

@ -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) {

View File

@ -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;
}

View File

@ -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 ) );
}
}
}

View File

@ -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 );

View File

@ -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 );
}
}

View File

@ -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() )
);
}

View File

@ -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

View File

@ -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 ) {

View File

@ -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) {

View File

@ -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) {

View File

@ -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 );
}

View File

@ -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();

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;