HHH-4698 - Better handling of JPA criteria expressions

git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@18268 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
Steve Ebersole 2009-12-18 15:32:39 +00:00
parent a87e031bd5
commit c1da5f1e3c
28 changed files with 2177 additions and 44 deletions

View File

@ -35,7 +35,7 @@ import java.io.Serializable;
*/
public class NamedParameterDescriptor implements Serializable {
private final String name;
private final Type expectedType;
private Type expectedType;
private final int[] sourceLocations;
private final boolean jpaStyle;
@ -61,4 +61,8 @@ public class NamedParameterDescriptor implements Serializable {
public boolean isJpaStyle() {
return jpaStyle;
}
public void resetExpectedType(Type type) {
this.expectedType = type;
}
}

View File

@ -27,8 +27,8 @@ import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.persistence.EntityNotFoundException;
import javax.persistence.EntityTransaction;
import javax.persistence.FlushModeType;
@ -59,6 +59,7 @@ import org.slf4j.LoggerFactory;
import org.hibernate.*;
import org.hibernate.cfg.Environment;
import org.hibernate.ejb.criteria.ValueConverter;
import org.hibernate.ejb.transaction.JoinableCMTTransaction;
import org.hibernate.ejb.util.ConfigurationHelper;
import org.hibernate.ejb.criteria.CriteriaQueryCompiler;
@ -66,6 +67,7 @@ import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.proxy.HibernateProxy;
import org.hibernate.transaction.TransactionFactory;
import org.hibernate.transform.BasicTransformerAdapter;
import org.hibernate.util.CollectionHelper;
import org.hibernate.util.JTAHelper;
@ -140,6 +142,45 @@ public abstract class AbstractEntityManagerImpl implements HibernateEntityManage
}
}
public <T> TypedQuery<T> createQuery(
String jpaqlString,
Class<T> resultClass,
Options options) {
try {
org.hibernate.Query hqlQuery = getSession().createQuery( jpaqlString );
if ( options.getConversions() != null ) {
hqlQuery.setResultTransformer( new ValueConversionResultTransformer( options.getConversions() ) );
}
else {
options.getResultMetadataValidator().validate( hqlQuery.getReturnTypes() );
}
return new QueryImpl<T>( hqlQuery, this, options.getNamedParameterExplicitTypes() );
}
catch ( HibernateException he ) {
throw convert( he );
}
}
private static class ValueConversionResultTransformer extends BasicTransformerAdapter {
private List<ValueConverter.Conversion> conversions;
private ValueConversionResultTransformer(List<ValueConverter.Conversion> conversions) {
this.conversions = conversions;
}
@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
? tuple[i]
: conversion.apply( tuple[i] );
}
return result.length == 1 ? result[0] : result;
}
}
private CriteriaQueryCompiler criteriaQueryCompiler;
public <T> TypedQuery<T> createQuery(CriteriaQuery<T> criteriaQuery) {

View File

@ -25,11 +25,16 @@ package org.hibernate.ejb;
import javax.persistence.PersistenceException;
import javax.persistence.LockModeType;
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.type.Type;
import java.util.List;
import java.util.Map;
/**
@ -108,4 +113,38 @@ public interface HibernateEntityManagerImplementor extends HibernateEntityManage
* @return the LockOptions
*/
public LockOptions getLockRequest(LockModeType lockModeType, Map<String, Object> properties);
public static interface Options {
public static interface ResultMetadataValidator {
public void validate(Type[] returnTypes);
}
/**
* Get the conversions for the individual tuples in the query results.
*
* @return Value conversions to be applied to the JPA QL results
*/
public List<ValueConverter.Conversion> getConversions();
/**
* Get the explicit parameter types. Generally speaking these would apply to implicit named
* parameters.
*
* @return The
*/
public Map<String,Class> getNamedParameterExplicitTypes();
public ResultMetadataValidator getResultMetadataValidator();
}
/**
* Used during "compiling" a JPA criteria query.
*
* @param jpaqlString The criteria query rendered as a JPA QL string
* @param resultClass The result type (the type expected in the result list)
* @param options The options to use to build the query.
* @param <T> The query type
* @return The typed query
*/
public <T> TypedQuery<T> createQuery(String jpaqlString, Class<T> resultClass, Options options);
}

View File

@ -25,9 +25,11 @@ package org.hibernate.ejb;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.persistence.NoResultException;
@ -56,6 +58,7 @@ import org.hibernate.engine.query.NamedParameterDescriptor;
import org.hibernate.engine.query.OrdinalParameterDescriptor;
import org.hibernate.hql.QueryExecutionRequestException;
import org.hibernate.impl.AbstractQueryImpl;
import org.hibernate.type.TypeFactory;
/**
* Hibernate implementation of both the {@link Query} and {@link TypedQuery} contracts.
@ -72,13 +75,20 @@ public class QueryImpl<X> extends org.hibernate.ejb.AbstractQueryImpl<X> impleme
private Set<Parameter<?>> parameters;
public QueryImpl(org.hibernate.Query query, AbstractEntityManagerImpl em) {
this( query, em, Collections.<String, Class>emptyMap() );
}
public QueryImpl(
org.hibernate.Query query,
AbstractEntityManagerImpl em,
Map<String,Class> namedParameterTypeRedefinitions) {
super( em );
this.query = query;
extractParameterInfo();
extractParameterInfo( namedParameterTypeRedefinitions );
}
@SuppressWarnings({ "unchecked", "RedundantCast" })
private void extractParameterInfo() {
private void extractParameterInfo(Map<String,Class> namedParameterTypeRedefinition) {
if ( ! AbstractQueryImpl.class.isInstance( query ) ) {
throw new IllegalStateException( "Unknown query type for parameter extraction" );
}
@ -90,12 +100,16 @@ public class QueryImpl<X> extends org.hibernate.ejb.AbstractQueryImpl<X> impleme
for ( String name : (Set<String>) queryImpl.getParameterMetadata().getNamedParameterNames() ) {
final NamedParameterDescriptor descriptor =
queryImpl.getParameterMetadata().getNamedParameterDescriptor( name );
final ParameterImpl parameter = new ParameterImpl(
name,
descriptor.getExpectedType() == null
? null
: descriptor.getExpectedType().getReturnedClass()
);
Class javaType = namedParameterTypeRedefinition.get( name );
if ( javaType != null ) {
descriptor.resetExpectedType(
TypeFactory.heuristicType( javaType.getName() )
);
}
else if ( descriptor.getExpectedType() != null ) {
javaType = descriptor.getExpectedType().getReturnedClass();
}
final ParameterImpl parameter = new ParameterImpl( name, javaType );
parameters.add( parameter );
if ( descriptor.isJpaStyle() ) {
if ( jpaPositionalIndices == null ) {

View File

@ -48,6 +48,7 @@ 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;
@ -1062,50 +1063,50 @@ public class CriteriaBuilderImpl implements CriteriaBuilder, Serializable {
/**
* {@inheritDoc}
*/
public Expression<Long> toLong(Expression<? extends Number> expression) {
return expression.as( Long.class );
public ExpressionImplementor<Long> toLong(Expression<? extends Number> expression) {
return ( (ExpressionImplementor<? extends Number>) expression ).asLong();
}
/**
* {@inheritDoc}
*/
public Expression<Integer> toInteger(Expression<? extends Number> expression) {
return expression.as( Integer.class );
public ExpressionImplementor<Integer> toInteger(Expression<? extends Number> expression) {
return ( (ExpressionImplementor<? extends Number>) expression ).asInteger();
}
/**
* {@inheritDoc}
*/
public Expression<Float> toFloat(Expression<? extends Number> expression) {
return expression.as( Float.class );
public ExpressionImplementor<Float> toFloat(Expression<? extends Number> expression) {
return ( (ExpressionImplementor<? extends Number>) expression ).asFloat();
}
/**
* {@inheritDoc}
*/
public Expression<Double> toDouble(Expression<? extends Number> expression) {
return expression.as( Double.class );
public ExpressionImplementor<Double> toDouble(Expression<? extends Number> expression) {
return ( (ExpressionImplementor<? extends Number>) expression ).asDouble();
}
/**
* {@inheritDoc}
*/
public Expression<BigDecimal> toBigDecimal(Expression<? extends Number> expression) {
return expression.as( BigDecimal.class );
public ExpressionImplementor<BigDecimal> toBigDecimal(Expression<? extends Number> expression) {
return ( (ExpressionImplementor<? extends Number>) expression ).asBigDecimal();
}
/**
* {@inheritDoc}
*/
public Expression<BigInteger> toBigInteger(Expression<? extends Number> expression) {
return expression.as( BigInteger.class );
public ExpressionImplementor<BigInteger> toBigInteger(Expression<? extends Number> expression) {
return ( (ExpressionImplementor<? extends Number>) expression ).asBigInteger();
}
/**
* {@inheritDoc}
*/
public Expression<String> toString(Expression<Character> characterExpression) {
return characterExpression.as( String.class );
public ExpressionImplementor<String> toString(Expression<Character> characterExpression) {
return ( (ExpressionImplementor<Character>) characterExpression ).asString();
}

View File

@ -55,6 +55,8 @@ import org.hibernate.util.StringHelper;
*/
public class CriteriaQueryCompiler {
public static interface ImplicitParameterBinding {
public String getParameterName();
public Class getJavaType();
public void bind(TypedQuery typedQuery);
}
@ -70,6 +72,8 @@ public class CriteriaQueryCompiler {
public static interface RenderedCriteriaQuery {
public String getQueryString();
public List<ValueConverter.Conversion> getValueConversions();
public HibernateEntityManagerImplementor.Options.ResultMetadataValidator getResultMetadataValidator();
}
private final HibernateEntityManagerImplementor entityManager;
@ -85,6 +89,7 @@ public class CriteriaQueryCompiler {
final Map<ParameterExpression<?>,String> explicitParameterMapping = new HashMap<ParameterExpression<?>,String>();
final Map<String,ParameterExpression<?>> explicitParameterNameMapping = new HashMap<String,ParameterExpression<?>>();
final List<ImplicitParameterBinding> implicitParameterBindings = new ArrayList<ImplicitParameterBinding>();
final Map<String,Class> implicitParameterTypes = new HashMap<String, Class>();
RenderingContext renderingContext = new RenderingContext() {
private int aliasCount = 0;
@ -110,6 +115,10 @@ public class CriteriaQueryCompiler {
public void registerImplicitParameterBinding(ImplicitParameterBinding binding) {
implicitParameterBindings.add( binding );
implicitParameterTypes.put(
binding.getParameterName(),
binding.getJavaType()
);
}
public String getCastType(Class javaType) {
@ -132,12 +141,26 @@ public class CriteriaQueryCompiler {
}
};
RenderedCriteriaQuery renderedCriteriaQuery = criteriaQueryImpl.render( renderingContext );
final RenderedCriteriaQuery renderedCriteriaQuery = criteriaQueryImpl.render( renderingContext );
TypedQuery<T> jpaqlQuery = entityManager.createQuery(
renderedCriteriaQuery.getQueryString(),
criteriaQuery.getResultType()
criteriaQuery.getResultType(),
new HibernateEntityManagerImplementor.Options() {
public List<ValueConverter.Conversion> getConversions() {
return renderedCriteriaQuery.getValueConversions();
}
public Map<String, Class> getNamedParameterExplicitTypes() {
return implicitParameterTypes;
}
public ResultMetadataValidator getResultMetadataValidator() {
return renderedCriteriaQuery.getResultMetadataValidator();
}
}
);
for ( ImplicitParameterBinding implicitParameterBinding : implicitParameterBindings ) {
implicitParameterBinding.bind( jpaqlQuery );
}

View File

@ -38,6 +38,9 @@ import javax.persistence.Tuple;
import javax.persistence.criteria.Subquery;
import javax.persistence.metamodel.EntityType;
import org.hibernate.ejb.HibernateEntityManagerImplementor;
import org.hibernate.type.Type;
/**
* The Hibernate implementation of the JPA {@link CriteriaQuery} contract. Mostly a set of delegation to its
* internal {@link QueryStructure}.
@ -350,6 +353,41 @@ public class CriteriaQueryImpl<T> extends AbstractNode implements CriteriaQuery<
public String getQueryString() {
return jpaqlQuery.toString();
}
@SuppressWarnings({ "unchecked" })
public List<ValueConverter.Conversion> getValueConversions() {
SelectionImplementor selection = (SelectionImplementor) queryStructure.getSelection();
return selection == null
? null
: selection.getConversions();
}
public HibernateEntityManagerImplementor.Options.ResultMetadataValidator getResultMetadataValidator() {
return new HibernateEntityManagerImplementor.Options.ResultMetadataValidator() {
public void validate(Type[] returnTypes) {
SelectionImplementor selection = (SelectionImplementor) queryStructure.getSelection();
if ( selection != null ) {
if ( selection.isCompoundSelection() ) {
if ( returnTypes.length != selection.getCompoundSelectionItems().size() ) {
throw new IllegalStateException(
"Number of return values [" + returnTypes.length +
"] did not match expected [" +
selection.getCompoundSelectionItems().size() + "]"
);
}
}
else {
if ( returnTypes.length > 1 ) {
throw new IllegalStateException(
"Number of return values [" + returnTypes.length +
"] did not match expected [1]"
);
}
}
}
}
};
}
};
}
}

View File

@ -0,0 +1,84 @@
/*
* 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.math.BigDecimal;
import java.math.BigInteger;
import javax.persistence.criteria.Expression;
/**
* TODO : javadoc
*
* @author Steve Ebersole
*/
public interface ExpressionImplementor<T> extends SelectionImplementor<T>, Expression<T>, Renderable {
/**
* See {@link javax.persistence.criteria.CriteriaBuilder#toLong}
*
* @return <tt>this</tt> but as a long
*/
public ExpressionImplementor<Long> asLong();
/**
* See {@link javax.persistence.criteria.CriteriaBuilder#toInteger}
*
* @return <tt>this</tt> but as an integer
*/
public ExpressionImplementor<Integer> asInteger();
/**
* See {@link javax.persistence.criteria.CriteriaBuilder#toFloat}
*
* @return <tt>this</tt> but as a float
*/
public ExpressionImplementor<Float> asFloat();
/**
* See {@link javax.persistence.criteria.CriteriaBuilder#toDouble}
*
* @return <tt>this</tt> but as a double
*/
public ExpressionImplementor<Double> asDouble();
/**
* See {@link javax.persistence.criteria.CriteriaBuilder#toBigDecimal}
*
* @return <tt>this</tt> but as a {@link BigDecimal}
*/
public ExpressionImplementor<BigDecimal> asBigDecimal();
/**
* See {@link javax.persistence.criteria.CriteriaBuilder#toBigInteger}
*
* @return <tt>this</tt> but as a {@link BigInteger}
*/
public ExpressionImplementor<BigInteger> asBigInteger();
/**
* See {@link javax.persistence.criteria.CriteriaBuilder#toString}
*
* @return <tt>this</tt> but as a string
*/
public ExpressionImplementor<String> asString();
}

View File

@ -0,0 +1,36 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2009, 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 java.util.List;
import javax.persistence.criteria.Selection;
/**
* TODO : javadoc
*
* @author Steve Ebersole
*/
public interface SelectionImplementor<X> extends TupleElementImplementor<X>, Selection<X> {
public List<ValueConverter.Conversion> getConversions();
}

View File

@ -1,10 +1,10 @@
/*
* 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.
* Copyright (c) 2009, 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
@ -21,16 +21,15 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.ejb.criteria.expression;
package org.hibernate.ejb.criteria;
import javax.persistence.criteria.Expression;
import org.hibernate.ejb.criteria.Renderable;
import javax.persistence.TupleElement;
/**
* TODO : javadoc
*
* @author Steve Ebersole
*/
public interface ExpressionImplementor<T> extends Expression<T>, Renderable {
public interface TupleElementImplementor<X> extends TupleElement<X> {
public ValueConverter.Conversion<X> getConversion();
}

View File

@ -0,0 +1,255 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2009, 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 java.math.BigDecimal;
import java.math.BigInteger;
/**
* Helper for generically converting a values into another type.
*
* @author Steve Ebersole
*/
public class ValueConverter {
private ValueConverter() {
}
public static interface Conversion<T> {
public T apply(Object value);
}
public static class ByteConversion implements Conversion<Byte> {
public static final ByteConversion INSTANCE = new ByteConversion();
@SuppressWarnings({ "UnnecessaryBoxing" })
public Byte apply(Object value) {
if ( value == null ) {
return null;
}
if ( Number.class.isInstance( value ) ) {
return Byte.valueOf( ( (Number) value ).byteValue() );
}
else if ( String.class.isInstance( value ) ) {
return Byte.valueOf( ( (String) value ) );
}
throw unknownConversion( value, Byte.class );
}
}
public static class ShortConversion implements Conversion<Short> {
public static final ShortConversion INSTANCE = new ShortConversion();
@SuppressWarnings({ "UnnecessaryBoxing" })
public Short apply(Object value) {
if ( value == null ) {
return null;
}
if ( Number.class.isInstance( value ) ) {
return Short.valueOf( ( (Number) value ).shortValue() );
}
else if ( String.class.isInstance( value ) ) {
return Short.valueOf( ( (String) value ) );
}
throw unknownConversion( value, Short.class );
}
}
public static class IntegerConversion implements Conversion<Integer> {
public static final IntegerConversion INSTANCE = new IntegerConversion();
@SuppressWarnings({ "UnnecessaryBoxing" })
public Integer apply(Object value) {
if ( value == null ) {
return null;
}
if ( Number.class.isInstance( value ) ) {
return Integer.valueOf( ( (Number) value ).intValue() );
}
else if ( String.class.isInstance( value ) ) {
return Integer.valueOf( ( (String) value ) );
}
throw unknownConversion( value, Integer.class );
}
}
public static class LongConversion implements Conversion<Long> {
public static final LongConversion INSTANCE = new LongConversion();
@SuppressWarnings({ "UnnecessaryBoxing" })
public Long apply(Object value) {
if ( value == null ) {
return null;
}
if ( Number.class.isInstance( value ) ) {
return Long.valueOf( ( (Number) value ).longValue() );
}
else if ( String.class.isInstance( value ) ) {
return Long.valueOf( ( (String) value ) );
}
throw unknownConversion( value, Long.class );
}
}
public static class FloatConversion implements Conversion<Float> {
public static final FloatConversion INSTANCE = new FloatConversion();
@SuppressWarnings({ "UnnecessaryBoxing" })
public Float apply(Object value) {
if ( value == null ) {
return null;
}
if ( Number.class.isInstance( value ) ) {
return Float.valueOf( ( (Number) value ).floatValue() );
}
else if ( String.class.isInstance( value ) ) {
return Float.valueOf( ( (String) value ) );
}
throw unknownConversion( value, Float.class );
}
}
public static class DoubleConversion implements Conversion<Double> {
public static final DoubleConversion INSTANCE = new DoubleConversion();
@SuppressWarnings({ "UnnecessaryBoxing" })
public Double apply(Object value) {
if ( value == null ) {
return null;
}
if ( Number.class.isInstance( value ) ) {
return Double.valueOf( ( (Number) value ).doubleValue() );
}
else if ( String.class.isInstance( value ) ) {
return Double.valueOf( ( (String) value ) );
}
throw unknownConversion( value, Double.class );
}
}
public static class BigIntegerConversion implements Conversion<BigInteger> {
public static final BigIntegerConversion INSTANCE = new BigIntegerConversion();
public BigInteger apply(Object value) {
if ( value == null ) {
return null;
}
if ( Number.class.isInstance( value ) ) {
return BigInteger.valueOf( ( (Number) value ).longValue() );
}
else if ( String.class.isInstance( value ) ) {
return new BigInteger( (String) value );
}
throw unknownConversion( value, BigInteger.class );
}
}
public static class BigDecimalConversion implements Conversion<BigDecimal> {
public static final BigDecimalConversion INSTANCE = new BigDecimalConversion();
public BigDecimal apply(Object value) {
if ( value == null ) {
return null;
}
if ( BigInteger.class.isInstance( value ) ) {
return new BigDecimal( (BigInteger) value );
}
else if ( Number.class.isInstance( value ) ) {
return BigDecimal.valueOf( ( (Number) value ).doubleValue() );
}
else if ( String.class.isInstance( value ) ) {
return new BigDecimal( (String) value );
}
throw unknownConversion( value, BigDecimal.class );
}
}
public static class StringConversion implements Conversion<String> {
public static final StringConversion INSTANCE = new StringConversion();
public String apply(Object value) {
return value == null ? null : value.toString();
}
}
private static IllegalArgumentException unknownConversion(Object value, Class type) {
return new IllegalArgumentException(
"Unaware how to convert value [" + value + "] to requested type [" + type.getName() + "]"
);
}
/**
* Convert the given value into the specified target type.
*
* @param value The value to convert
* @param targetType The type to which it should be converted
*
* @return The converted value.
*/
@SuppressWarnings({ "unchecked" })
public static <T> T convert(Object value, Class<T> targetType) {
if ( value == null ) {
return null;
}
if ( targetType.equals( value.getClass() ) ) {
return (T) value;
}
Conversion<T> conversion = determineAppropriateConversion( targetType );
if ( conversion == null ) {
throw unknownConversion( value, targetType );
}
return conversion.apply( value );
}
/**
* Determine the appropriate {@link Conversion} strategy for converting a value
* to the given target type
*
* @param targetType The target type (to which we want to convert values).
* @param <T> parameterized type for the target type.
* @return The conversion
*/
@SuppressWarnings({ "unchecked" })
public static <T> Conversion<T> determineAppropriateConversion(Class<T> targetType) {
if ( String.class.equals( targetType ) ) {
return (Conversion<T>) StringConversion.INSTANCE;
}
if ( Byte.class.equals( targetType ) ) {
return (Conversion<T>) ByteConversion.INSTANCE;
}
if ( Short.class.equals( targetType ) ) {
return (Conversion<T>) ShortConversion.INSTANCE;
}
if ( Integer.class.equals( targetType ) ) {
return (Conversion<T>) IntegerConversion.INSTANCE;
}
if ( Long.class.equals( targetType ) ) {
return (Conversion<T>) LongConversion.INSTANCE;
}
if ( Float.class.equals( targetType ) ) {
return (Conversion<T>) FloatConversion.INSTANCE;
}
if ( Double.class.equals( targetType ) ) {
return (Conversion<T>) DoubleConversion.INSTANCE;
}
if ( BigInteger.class.equals( targetType ) ) {
return (Conversion<T>) BigIntegerConversion.INSTANCE;
}
if ( BigDecimal.class.equals( targetType ) ) {
return (Conversion<T>) BigDecimalConversion.INSTANCE;
}
return null;
}
}

View File

@ -23,22 +23,27 @@
*/
package org.hibernate.ejb.criteria.expression;
import javax.persistence.TupleElement;
import org.hibernate.ejb.criteria.AbstractNode;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
import org.hibernate.ejb.criteria.TupleElementImplementor;
import org.hibernate.ejb.criteria.ValueConverter;
/**
* TODO : javadoc
*
* @author Steve Ebersole
*/
public abstract class AbstractTupleElement<X> extends AbstractNode implements TupleElement<X> {
private final Class<X> javaType;
public abstract class AbstractTupleElement<X>
extends AbstractNode
implements TupleElementImplementor<X> {
private final Class originalJavaType;
private Class<X> javaType;
private String alias;
private ValueConverter.Conversion<X> conversion;
protected AbstractTupleElement(CriteriaBuilderImpl criteriaBuilder, Class<X> javaType) {
super( criteriaBuilder );
this.originalJavaType = javaType;
this.javaType = javaType;
}
@ -49,6 +54,26 @@ public abstract class AbstractTupleElement<X> extends AbstractNode implements Tu
return javaType;
}
@SuppressWarnings({ "unchecked" })
protected void resetJavaType(Class targetType) {
this.javaType = targetType;
// this.conversion = javaType.equals( originalJavaType )
// ? null
// : ValueConverter.determineAppropriateConversion( javaType );
this.conversion = ValueConverter.determineAppropriateConversion( javaType );
}
protected void forceConversion(ValueConverter.Conversion<X> conversion) {
this.conversion = conversion;
}
/**
* {@inheritDoc}
*/
public ValueConverter.Conversion<X> getConversion() {
return conversion;
}
/**
* {@inheritDoc}
*/

View File

@ -23,6 +23,7 @@
*/
package org.hibernate.ejb.criteria.expression;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.Tuple;
import javax.persistence.criteria.CompoundSelection;
@ -32,6 +33,8 @@ import org.hibernate.ejb.criteria.CriteriaQueryCompiler;
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;
/**
* The Hibernate implementation of the JPA {@link CompoundSelection}
@ -62,6 +65,21 @@ public class CompoundSelectionImpl<X> extends SelectionImpl<X> implements Compou
return selectionItems;
}
@Override
public List<ValueConverter.Conversion> getConversions() {
if ( isConstructor ) {
return null;
}
boolean foundConversions = false;
ArrayList<ValueConverter.Conversion> conversions = new ArrayList<ValueConverter.Conversion>();
for ( Selection selection : getCompoundSelectionItems() ) {
ValueConverter.Conversion conversion = ( (TupleElementImplementor) selection ).getConversion();
conversions.add( conversion );
foundConversions = foundConversions || conversion != null;
}
return foundConversions ? null : conversions;
}
public void registerParameters(ParameterRegistry registry) {
for ( Selection selectionItem : getCompoundSelectionItems() ) {
Helper.possibleParameter(selectionItem, registry);

View File

@ -23,11 +23,14 @@
*/
package org.hibernate.ejb.criteria.expression;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Collection;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Predicate;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
import org.hibernate.ejb.criteria.ExpressionImplementor;
import org.hibernate.ejb.criteria.expression.function.CastFunction;
/**
@ -93,4 +96,67 @@ public abstract class ExpressionImpl<T>
public Predicate in(Expression<Collection<?>> values) {
return queryBuilder().in( this, values );
}
/**
* {@inheritDoc}
*/
@SuppressWarnings({ "unchecked" })
public ExpressionImplementor<Long> asLong() {
resetJavaType( Long.class );
return (ExpressionImplementor<Long>) this;
}
/**
* {@inheritDoc}
*/
@SuppressWarnings({ "unchecked" })
public ExpressionImplementor<Integer> asInteger() {
resetJavaType( Integer.class );
return (ExpressionImplementor<Integer>) this;
}
/**
* {@inheritDoc}
*/
@SuppressWarnings({ "unchecked" })
public ExpressionImplementor<Float> asFloat() {
resetJavaType( Float.class );
return (ExpressionImplementor<Float>) this;
}
/**
* {@inheritDoc}
*/
@SuppressWarnings({ "unchecked" })
public ExpressionImplementor<Double> asDouble() {
resetJavaType( Double.class );
return (ExpressionImplementor<Double>) this;
}
/**
* {@inheritDoc}
*/
@SuppressWarnings({ "unchecked" })
public ExpressionImplementor<BigDecimal> asBigDecimal() {
resetJavaType( BigDecimal.class );
return (ExpressionImplementor<BigDecimal>) this;
}
/**
* {@inheritDoc}
*/
@SuppressWarnings({ "unchecked" })
public ExpressionImplementor<BigInteger> asBigInteger() {
resetJavaType( BigInteger.class );
return (ExpressionImplementor<BigInteger>) this;
}
/**
* {@inheritDoc}
*/
@SuppressWarnings({ "unchecked" })
public ExpressionImplementor<String> asString() {
resetJavaType( String.class );
return (ExpressionImplementor<String>) this;
}
}

View File

@ -25,6 +25,7 @@ package org.hibernate.ejb.criteria.expression;
import javax.persistence.TypedQuery;
import org.hibernate.ejb.criteria.ValueConverter;
import org.hibernate.ejb.criteria.ParameterRegistry;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaQueryCompiler;
@ -35,7 +36,7 @@ import org.hibernate.ejb.criteria.CriteriaQueryCompiler;
* @author Steve Ebersole
*/
public class LiteralExpression<T> extends ExpressionImpl<T> {
private final T literal;
private Object literal;
@SuppressWarnings({ "unchecked" })
public LiteralExpression(CriteriaBuilderImpl criteriaBuilder, T literal) {
@ -51,18 +52,27 @@ public class LiteralExpression<T> extends ExpressionImpl<T> {
this.literal = literal;
}
@SuppressWarnings({ "unchecked" })
public T getLiteral() {
return literal;
return (T) literal;
}
public void registerParameters(ParameterRegistry registry) {
// nothign to do
// nothing to do
}
public String render(CriteriaQueryCompiler.RenderingContext renderingContext) {
final String parameterName = renderingContext.generateParameterName();
renderingContext.registerImplicitParameterBinding(
new CriteriaQueryCompiler.ImplicitParameterBinding() {
public String getParameterName() {
return parameterName;
}
public Class getJavaType() {
return LiteralExpression.this.getJavaType();
}
public void bind(TypedQuery typedQuery) {
typedQuery.setParameter( parameterName, getLiteral() );
}
@ -74,4 +84,19 @@ public class LiteralExpression<T> extends ExpressionImpl<T> {
public String renderProjection(CriteriaQueryCompiler.RenderingContext renderingContext) {
return render( renderingContext );
}
@Override
@SuppressWarnings({ "unchecked" })
protected void resetJavaType(Class targetType) {
super.resetJavaType( targetType );
ValueConverter.Conversion conversion = getConversion();
if ( conversion == null ) {
conversion = ValueConverter.determineAppropriateConversion( targetType );
forceConversion( conversion );
}
if ( conversion != null ) {
literal = conversion.apply( literal );
}
}
}

View File

@ -23,11 +23,14 @@
*/
package org.hibernate.ejb.criteria.expression;
import java.util.Collections;
import java.util.List;
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;
/**
* The Hibernate implementation of the JPA {@link Selection}
@ -37,7 +40,7 @@ import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
*/
public abstract class SelectionImpl<X>
extends AbstractTupleElement<X>
implements Selection<X>, ParameterContainer {
implements SelectionImplementor<X>, ParameterContainer {
public SelectionImpl(CriteriaBuilderImpl criteriaBuilder, Class<X> javaType) {
super( criteriaBuilder, javaType );
}
@ -51,6 +54,12 @@ public abstract class SelectionImpl<X>
return false;
}
public List<ValueConverter.Conversion> getConversions() {
return getConversion() == null
? null
: Collections.singletonList( (ValueConverter.Conversion) getConversion() );
}
public List<Selection<?>> getCompoundSelectionItems() {
throw new IllegalStateException( "Not a compund selection" );
}

View File

@ -25,6 +25,7 @@ package org.hibernate.ejb.criteria.predicate;
import javax.persistence.criteria.Expression;
import org.hibernate.ejb.criteria.ValueConverter;
import org.hibernate.ejb.criteria.ParameterRegistry;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaQueryCompiler;
@ -62,7 +63,29 @@ public class ComparisonPredicate extends AbstractSimplePredicate implements Bina
super( criteriaBuilder );
this.comparisonOperator = comparisonOperator;
this.leftHandSide = leftHandSide;
this.rightHandSide = new LiteralExpression( criteriaBuilder, rightHandSide );
if ( Number.class.isAssignableFrom( leftHandSide.getJavaType() ) ) {
this.rightHandSide = new LiteralExpression(
criteriaBuilder,
ValueConverter.convert( rightHandSide, (Class<Number>) leftHandSide.getJavaType() )
);
}
else {
this.rightHandSide = new LiteralExpression( criteriaBuilder, rightHandSide );
}
}
public <N extends Number> ComparisonPredicate(
CriteriaBuilderImpl criteriaBuilder,
ComparisonOperator comparisonOperator,
Expression<N> leftHandSide,
Number rightHandSide) {
super( criteriaBuilder );
this.comparisonOperator = comparisonOperator;
this.leftHandSide = leftHandSide;
this.rightHandSide = new LiteralExpression<N>(
criteriaBuilder,
ValueConverter.convert( rightHandSide, leftHandSide.getJavaType() )
);
}
public ComparisonOperator getComparisonOperator() {

View File

@ -0,0 +1,190 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2009, 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 java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import javax.persistence.metamodel.EntityType;
import org.hibernate.ejb.criteria.predicate.ComparisonPredicate;
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.MetamodelImpl;
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;
/**
* TODO : javadoc
*
* @author Steve Ebersole
*/
public class QueryBuilderTest extends TestCase {
@Override
public Class[] getAnnotatedClasses() {
return new Class[] {
Address.class,
Alias.class,
Country.class,
CreditCard.class,
Customer.class,
Info.class,
LineItem.class,
Order.class,
Phone.class,
Product.class,
ShelfLife.class,
Spouse.class
};
}
public void testEqualityComparisonLiteralConversion() {
EntityManager em = getOrCreateEntityManager();
em.getTransaction().begin();
CriteriaBuilderImpl cb = (CriteriaBuilderImpl) em.getCriteriaBuilder();
MetamodelImpl mm = (MetamodelImpl) em.getMetamodel();
CriteriaQuery<Integer> cquery = cb.createQuery( Integer.class );
Root<Product> product = cquery.from( Product.class );
EntityType<Product> Product_ = mm.entity( Product.class );
cquery.select(
cb.toInteger(
product.get(
Product_.getSingularAttribute("quantity", Integer.class))
)
);
ComparisonPredicate predicate = (ComparisonPredicate) cb.equal(
product.get( Product_.getSingularAttribute( "partNumber", Long.class ) ),
373767373
);
assertEquals( Long.class, predicate.getRightHandOperand().getJavaType() );
cquery.where( predicate );
em.createQuery( cquery ).getResultList();
predicate = (ComparisonPredicate) cb.ge(
cb.length( product.get( Product_.getSingularAttribute( "name", String.class ) ) ),
4L
);
assertEquals( Integer.class, predicate.getRightHandOperand().getJavaType() );
cquery.where( predicate );
em.createQuery( cquery ).getResultList();
em.getTransaction().commit();
em.close();
}
public void testTypeConversion() {
EntityManager em = getOrCreateEntityManager();
em.getTransaction().begin();
CriteriaBuilderImpl cb = (CriteriaBuilderImpl) em.getCriteriaBuilder();
MetamodelImpl mm = (MetamodelImpl) em.getMetamodel();
EntityType<Product> Product_ = mm.entity( Product.class );
// toFloat
CriteriaQuery<Float> floatQuery = cb.createQuery( Float.class );
Root<Product> product = floatQuery.from( Product.class );
floatQuery.select(
cb.toFloat(
product.get(Product_.getSingularAttribute("quantity", Integer.class))
)
);
em.createQuery( floatQuery ).getResultList();
// toDouble
CriteriaQuery<Double> doubleQuery = cb.createQuery(Double.class);
product = doubleQuery.from( Product.class );
doubleQuery.select(
cb.toDouble(
product.get(Product_.getSingularAttribute("quantity", Integer.class))
)
);
em.createQuery( doubleQuery ).getResultList();
em.getTransaction().commit();
em.close();
}
public void testConstructor() {
EntityManager em = getOrCreateEntityManager();
em.getTransaction().begin();
CriteriaBuilderImpl cb = (CriteriaBuilderImpl) em.getCriteriaBuilder();
MetamodelImpl mm = (MetamodelImpl) em.getMetamodel();
CriteriaQuery<Customer> cquery = cb.createQuery(Customer.class);
Root<Customer> customer = cquery.from(Customer.class);
EntityType<Customer> Customer_ = customer.getModel();
cquery.select(
cb.construct(
Customer.class,
customer.get(Customer_.getSingularAttribute("id", String.class)),
customer.get(Customer_.getSingularAttribute("name", String.class))
)
);
TypedQuery<Customer> tq = em.createQuery(cquery);
tq.getResultList();
em.getTransaction().commit();
em.close();
}
public void testDateTimeFunctions() {
EntityManager em = getOrCreateEntityManager();
em.getTransaction().begin();
CriteriaBuilderImpl cb = (CriteriaBuilderImpl) em.getCriteriaBuilder();
MetamodelImpl mm = (MetamodelImpl) em.getMetamodel();
CriteriaQuery<java.sql.Date> dateQuery = cb.createQuery(java.sql.Date.class);
dateQuery.from( Customer.class );
dateQuery.select( cb.currentDate() );
em.createQuery( dateQuery ).getResultList();
CriteriaQuery<java.sql.Time> timeQuery = cb.createQuery(java.sql.Time.class);
timeQuery.from( Customer.class );
timeQuery.select( cb.currentTime() );
em.createQuery( timeQuery ).getResultList();
CriteriaQuery<java.sql.Timestamp> tsQuery = cb.createQuery(java.sql.Timestamp.class);
tsQuery.from( Customer.class );
tsQuery.select( cb.currentTimestamp() );
em.createQuery( tsQuery ).getResultList();
em.getTransaction().commit();
em.close();
}
}

View File

@ -0,0 +1,124 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2009, 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.metamodel;
import java.util.Collection;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
/**
* TODO : javadoc
*
* @author Steve Ebersole
*/
@Entity
@Table(name = "ADDRESS")
public class Address implements java.io.Serializable {
private String id;
private String street;
private String city;
private String state;
private String zip;
private Collection<Phone> phones = new java.util.ArrayList<Phone>();
public Address() {
}
public Address(String id, String street, String city, String state, String zip) {
this.id = id;
this.street = street;
this.city = city;
this.state = state;
this.zip = zip;
}
public Address(String id, String street, String city, String state, String zip,
Collection<Phone> phones) {
this.id = id;
this.street = street;
this.city = city;
this.state = state;
this.zip = zip;
this.phones = phones;
}
@Id
@Column(name = "ID")
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@Column(name = "STREET")
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
@Column(name = "CITY")
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
@Column(name = "STATE")
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
@Column(name = "ZIP")
public String getZip() {
return zip;
}
public void setZip(String zip) {
this.zip = zip;
}
@OneToMany(cascade = CascadeType.ALL, mappedBy = "address")
public Collection<Phone> getPhones() {
return phones;
}
public void setPhones(Collection<Phone> phones) {
this.phones = phones;
}
}

View File

@ -0,0 +1,123 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2009, 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.metamodel;
import java.util.Collection;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
/**
* TODO : javadoc
*
* @author Steve Ebersole
*/
@Entity
@Table(name = "ALIAS_TABLE")
public class Alias implements java.io.Serializable {
private String id;
private String alias;
private Customer customerNoop;
private Collection<Customer> customersNoop = new java.util.ArrayList<Customer>();
private Collection<Customer> customers = new java.util.ArrayList<Customer>();
public Alias() {
}
public Alias(String id, String alias) {
this.id = id;
this.alias = alias;
}
@Id
@Column(name = "ID")
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@Column(name = "ALIAS")
public String getAlias() {
return alias;
}
public void setAlias(String alias) {
this.alias = alias;
}
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "FK1_FOR_CUSTOMER_TABLE", insertable = false, updatable = false)
public Customer getCustomerNoop() {
return customerNoop;
}
public void setCustomerNoop(Customer customerNoop) {
this.customerNoop = customerNoop;
}
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name = "FKS_ANOOP_CNOOP",
joinColumns =
@JoinColumn(
name = "FK2_FOR_ALIAS_TABLE", referencedColumnName = "ID"),
inverseJoinColumns =
@JoinColumn(
name = "FK8_FOR_CUSTOMER_TABLE", referencedColumnName = "ID")
)
public Collection<Customer> getCustomersNoop() {
return customersNoop;
}
public void setCustomersNoop(Collection<Customer> customersNoop) {
this.customersNoop = customersNoop;
}
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name = "FKS_ALIAS_CUSTOMER",
joinColumns =
@JoinColumn(
name = "FK_FOR_ALIAS_TABLE", referencedColumnName = "ID"),
inverseJoinColumns =
@JoinColumn(
name = "FK_FOR_CUSTOMER_TABLE", referencedColumnName = "ID")
)
public Collection<Customer> getCustomers() {
return customers;
}
public void setCustomers(Collection<Customer> customers) {
this.customers = customers;
}
}

View File

@ -0,0 +1,65 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2009, 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.metamodel;
import javax.persistence.Basic;
import javax.persistence.Embeddable;
/**
* TODO : javadoc
*
* @author Steve Ebersole
*/
@Embeddable
public class Country implements java.io.Serializable {
private String country;
private String code;
public Country() {
}
public Country(String v1, String v2) {
country = v1;
code = v2;
}
@Basic
public String getCountry() {
return country;
}
public void setCountry(String v) {
country = v;
}
@Basic
public String getCode() {
return code;
}
public void setCode(String v) {
code = v;
}
}

View File

@ -0,0 +1,153 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2009, 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.metamodel;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToOne;
import javax.persistence.Table;
/**
* TODO : javadoc
*
* @author Steve Ebersole
*/
@Entity
@Table(name = "CREDITCARD_TABLE")
public class CreditCard implements java.io.Serializable {
private String id;
private String number;
private String type;
private String expires;
private boolean approved;
private double balance;
private Order order;
private Customer customer;
public CreditCard() {
}
public CreditCard(
String v1, String v2, String v3, String v4,
boolean v5, double v6, Order v7, Customer v8) {
id = v1;
number = v2;
type = v3;
expires = v4;
approved = v5;
balance = v6;
order = v7;
customer = v8;
}
public CreditCard(
String v1, String v2, String v3, String v4,
boolean v5, double v6) {
id = v1;
number = v2;
type = v3;
expires = v4;
approved = v5;
balance = v6;
}
@Id
@Column(name = "ID")
public String getId() {
return id;
}
public void setId(String v) {
id = v;
}
@Column(name = "CREDITCARD_NUMBER")
public String getNumber() {
return number;
}
public void setNumber(String v) {
number = v;
}
@Column(name = "TYPE")
public String getType() {
return type;
}
public void setType(String v) {
type = v;
}
@Column(name = "EXPIRES")
public String getExpires() {
return expires;
}
public void setExpires(String v) {
expires = v;
}
@Column(name = "APPROVED")
public boolean getApproved() {
return approved;
}
public void setApproved(boolean v) {
approved = v;
}
@Column(name = "BALANCE")
public double getBalance() {
return balance;
}
public void setBalance(double v) {
balance = v;
}
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "FK_FOR_ORDER_TABLE")
public Order getOrder() {
return order;
}
public void setOrder(Order v) {
order = v;
}
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "FK3_FOR_CUSTOMER_TABLE")
public Customer getCustomer() {
return customer;
}
public void setCustomer(Customer v) {
customer = v;
}
}

View File

@ -0,0 +1,172 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2009, 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.metamodel;
import java.util.Collection;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
/**
* TODO : javadoc
*
* @author Steve Ebersole
*/
@Entity
@Table(name = "CUSTOMER_TABLE")
public class Customer implements java.io.Serializable {
private String id;
private String name;
private Address home;
private Address work;
private Country country;
private Spouse spouse;
private Collection<CreditCard> creditCards = new java.util.ArrayList<CreditCard>();
private Collection<Order> orders = new java.util.ArrayList<Order>();
private Collection<Alias> aliases = new java.util.ArrayList<Alias>();
private Collection<Alias> aliasesNoop = new java.util.ArrayList<Alias>();
public Customer() {
}
public Customer(String id, String name) {
this.id = id;
this.name = name;
}
public Customer(String id, String name, Country country) {
this.id = id;
this.name = name;
this.country = country;
}
public Customer(String id, String name, Address home,
Address work, Country country) {
this.id = id;
this.name = name;
this.home = home;
this.work = work;
this.country = country;
}
@Id
@Column(name = "ID")
public String getId() {
return id;
}
public void setId(String v) {
this.id = v;
}
@Column(name = "NAME")
public String getName() {
return name;
}
public void setName(String v) {
this.name = v;
}
@Embedded
public Country getCountry() {
return country;
}
public void setCountry(Country v) {
this.country = v;
}
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "FK6_FOR_CUSTOMER_TABLE")
public Address getHome() {
return home;
}
public void setHome(Address v) {
this.home = v;
}
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "FK5_FOR_CUSTOMER_TABLE")
public Address getWork() {
return work;
}
public void setWork(Address v) {
this.work = v;
}
@OneToOne(cascade = CascadeType.ALL, mappedBy = "customer")
public Spouse getSpouse() {
return spouse;
}
public void setSpouse(Spouse v) {
this.spouse = v;
}
@OneToMany(cascade = CascadeType.ALL, mappedBy = "customer")
public Collection<CreditCard> getCreditCards() {
return creditCards;
}
public void setCreditCards(Collection<CreditCard> v) {
this.creditCards = v;
}
@OneToMany(cascade = CascadeType.ALL, mappedBy = "customer")
public Collection<Order> getOrders() {
return orders;
}
public void setOrders(Collection<Order> v) {
this.orders = v;
}
@ManyToMany(cascade = CascadeType.ALL, mappedBy = "customers")
public Collection<Alias> getAliases() {
return aliases;
}
public void setAliases(Collection<Alias> v) {
this.aliases = v;
}
@ManyToMany(cascade = CascadeType.ALL, mappedBy = "customersNoop")
public Collection<Alias> getAliasesNoop() {
return aliasesNoop;
}
public void setAliasesNoop(Collection<Alias> v) {
this.aliasesNoop = v;
}
}

View File

@ -0,0 +1,124 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2009, 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.metamodel;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Table;
/**
* TODO : javadoc
*
* @author Steve Ebersole
*/
@Entity
@Table(name = "INFO_TABLE")
public class Info implements java.io.Serializable {
private String id;
private String street;
private String city;
private String state;
private String zip;
private Spouse spouse;
public Info() {
}
public Info(String v1, String v2, String v3, String v4, String v5) {
id = v1;
street = v2;
city = v3;
state = v4;
zip = v5;
}
public Info(
String v1, String v2, String v3, String v4,
String v5, Spouse v6) {
id = v1;
street = v2;
city = v3;
state = v4;
zip = v5;
spouse = v6;
}
@Id
@Column(name = "ID")
public String getId() {
return id;
}
public void setId(String v) {
id = v;
}
@Column(name = "INFOSTREET")
public String getStreet() {
return street;
}
public void setStreet(String v) {
street = v;
}
@Column(name = "INFOSTATE")
public String getState() {
return state;
}
public void setState(String v) {
state = v;
}
@Column(name = "INFOCITY")
public String getCity() {
return city;
}
public void setCity(String v) {
city = v;
}
@Column(name = "INFOZIP")
public String getZip() {
return zip;
}
public void setZip(String v) {
zip = v;
}
@OneToOne(mappedBy = "info")
public Spouse getSpouse() {
return spouse;
}
public void setSpouse(Spouse v) {
this.spouse = v;
}
}

View File

@ -0,0 +1,99 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2009, 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.metamodel;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
/**
* TODO : javadoc
*
* @author Steve Ebersole
*/
@Entity
@Table(name = "LINEITEM_TABLE")
public class LineItem implements java.io.Serializable {
private String id;
private int quantity;
private Order order;
private Product product;
public LineItem() {
}
public LineItem(String v1, int v2, Order v3, Product v4) {
id = v1;
quantity = v2;
order = v3;
product = v4;
}
public LineItem(String v1, int v2) {
id = v1;
quantity = v2;
}
@Id
@Column(name = "ID")
public String getId() {
return id;
}
public void setId(String v) {
id = v;
}
@Column(name = "QUANTITY")
public int getQuantity() {
return quantity;
}
public void setQuantity(int v) {
quantity = v;
}
@ManyToOne
@JoinColumn(name = "FK1_FOR_ORDER_TABLE")
public Order getOrder() {
return order;
}
public void setOrder(Order v) {
order = v;
}
@ManyToOne
@JoinColumn(name = "FK_FOR_PRODUCT_TABLE")
public Product getProduct() {
return product;
}
public void setProduct(Product v) {
product = v;
}
}

View File

@ -0,0 +1,141 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2009, 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.metamodel;
import java.util.Collection;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
/**
* TODO : javadoc
*
* @author Steve Ebersole
*/
@Entity
@Table(name = "ORDER_TABLE")
public class Order implements java.io.Serializable {
private String id;
private double totalPrice;
private Customer customer;
private CreditCard creditCard;
private LineItem sampleLineItem;
private Collection<LineItem> lineItems = new java.util.ArrayList<LineItem>();
public Order() {
}
public Order(String id, double totalPrice) {
this.id = id;
this.totalPrice = totalPrice;
}
public Order(String id, Customer customer) {
this.id = id;
this.customer = customer;
}
public Order(String id) {
this.id = id;
}
//====================================================================
// getters and setters for State fields
@Id
@Column(name = "ID")
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@Column(name = "TOTALPRICE")
public double getTotalPrice() {
return totalPrice;
}
public void setTotalPrice(double price) {
this.totalPrice = price;
}
//====================================================================
// getters and setters for Association fields
// MANYx1
@ManyToOne
@JoinColumn(
name = "FK4_FOR_CUSTOMER_TABLE")
public Customer getCustomer() {
return customer;
}
public void setCustomer(Customer customer) {
this.customer = customer;
}
//1x1
@OneToOne(mappedBy = "order")
public CreditCard getCreditCard() {
return creditCard;
}
public void setCreditCard(CreditCard cc) {
this.creditCard = cc;
}
// 1x1
@OneToOne(cascade = CascadeType.REMOVE)
@JoinColumn(
name = "FK0_FOR_LINEITEM_TABLE")
public LineItem getSampleLineItem() {
return sampleLineItem;
}
public void setSampleLineItem(LineItem l) {
this.sampleLineItem = l;
}
//1xMANY
@OneToMany(cascade = CascadeType.ALL, mappedBy = "order")
public Collection<LineItem> getLineItems() {
return lineItems;
}
public void setLineItems(Collection<LineItem> c) {
this.lineItems = c;
}
}

View File

@ -0,0 +1,99 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2009, 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.metamodel;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
/**
* TODO : javadoc
*
* @author Steve Ebersole
*/
@Entity
@Table(name = "PHONE_TABLE")
public class Phone implements java.io.Serializable {
private String id;
private String area;
private String number;
private Address address;
public Phone() {
}
public Phone(String v1, String v2, String v3) {
id = v1;
area = v2;
number = v3;
}
public Phone(String v1, String v2, String v3, Address v4) {
id = v1;
area = v2;
number = v3;
address = v4;
}
@Id
@Column(name = "ID")
public String getId() {
return id;
}
public void setId(String v) {
id = v;
}
@Column(name = "AREA")
public String getArea() {
return area;
}
public void setArea(String v) {
area = v;
}
@Column(name = "PHONE_NUMBER")
public String getNumber() {
return number;
}
public void setNumber(String v) {
number = v;
}
@ManyToOne
@JoinColumn(name = "FK_FOR_ADDRESS")
public Address getAddress() {
return address;
}
public void setAddress(Address a) {
address = a;
}
}

View File

@ -0,0 +1,143 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2009, 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.metamodel;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;
/**
* TODO : javadoc
*
* @author Steve Ebersole
*/
@Entity
@Table(name = "SPOUSE_TABLE")
public class Spouse implements java.io.Serializable {
private String id;
private String first;
private String maiden;
private String last;
private String sNumber;
private Info info;
private Customer customer;
public Spouse() {
}
public Spouse(
String v1, String v2, String v3, String v4,
String v5, Info v6) {
id = v1;
first = v2;
maiden = v3;
last = v4;
sNumber = v5;
info = v6;
}
public Spouse(
String v1, String v2, String v3, String v4,
String v5, Info v6, Customer v7) {
id = v1;
first = v2;
maiden = v3;
last = v4;
sNumber = v5;
info = v6;
customer = v7;
}
@Id
@Column(name = "ID")
public String getId() {
return id;
}
public void setId(String v) {
id = v;
}
@Column(name = "FIRSTNAME")
public String getFirstName() {
return first;
}
public void setFirstName(String v) {
first = v;
}
@Column(name = "MAIDENNAME")
public String getMaidenName() {
return maiden;
}
public void setMaidenName(String v) {
maiden = v;
}
@Column(name = "LASTNAME")
public String getLastName() {
return last;
}
public void setLastName(String v) {
last = v;
}
@Column(name = "SOCSECNUM")
public String getSocialSecurityNumber() {
return sNumber;
}
public void setSocialSecurityNumber(String v) {
sNumber = v;
}
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "FK_FOR_INFO_TABLE")
public Info getInfo() {
return info;
}
public void setInfo(Info v) {
info = v;
}
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "FK7_FOR_CUSTOMER_TABLE")
public Customer getCustomer() {
return customer;
}
public void setCustomer(Customer v) {
customer = v;
}
}