HHH-4203 - Implement JPA 2.0 criteria apis (compiling)

git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@17830 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
Steve Ebersole 2009-10-24 21:37:27 +00:00
parent b61332b10b
commit 9a1a95b2a2
70 changed files with 1339 additions and 401 deletions

View File

@ -35,10 +35,9 @@ import javax.persistence.spi.PersistenceUnitTransactionType;
import javax.persistence.spi.LoadState;
import org.hibernate.SessionFactory;
import org.hibernate.Hibernate;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.cfg.Configuration;
import org.hibernate.ejb.criteria.QueryBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
import org.hibernate.ejb.metamodel.MetamodelImpl;
import org.hibernate.ejb.util.PersistenceUtilHelper;
@ -54,7 +53,7 @@ public class EntityManagerFactoryImpl implements HibernateEntityManagerFactory {
private final PersistenceUnitTransactionType transactionType;
private final boolean discardOnClose;
private final Class sessionInterceptorClass;
private final QueryBuilderImpl criteriaQueryBuilder;
private final CriteriaBuilderImpl criteriaBuilder;
private final Metamodel metamodel;
private final HibernatePersistenceUnitUtil util;
@ -77,7 +76,7 @@ public class EntityManagerFactoryImpl implements HibernateEntityManagerFactory {
else {
this.metamodel = null;
}
this.criteriaQueryBuilder = new QueryBuilderImpl( this );
this.criteriaBuilder = new CriteriaBuilderImpl( this );
this.util = new HibernatePersistenceUnitUtil( this );
}
@ -94,7 +93,7 @@ public class EntityManagerFactoryImpl implements HibernateEntityManagerFactory {
}
public CriteriaBuilder getCriteriaBuilder() {
return criteriaQueryBuilder;
return criteriaBuilder;
}
public Metamodel getMetamodel() {

View File

@ -50,12 +50,12 @@ public abstract class AbstractBasicPluralJoin<O,C,E>
implements PluralJoin<O,C,E>, Fetch<O,E> {
public AbstractBasicPluralJoin(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
Class<E> javaType,
PathImpl<O> lhs,
PluralAttribute<? super O, ?, ?> joinProperty,
JoinType joinType) {
super(queryBuilder, javaType, lhs, joinProperty, joinType);
super( criteriaBuilder, javaType, lhs, joinProperty, joinType);
}
@Override

View File

@ -24,24 +24,24 @@
package org.hibernate.ejb.criteria;
/**
* All nodes in a criteria query tree will generally need access to the {@link QueryBuilderImpl} from which they
* All nodes in a criteria query tree will generally need access to the {@link CriteriaBuilderImpl} from which they
* come. This base class provides convenient, consistent support for that.
*
* @author Steve Ebersole
*/
public class AbstractNode {
private final QueryBuilderImpl queryBuilder;
private final CriteriaBuilderImpl criteriaBuilder;
public AbstractNode(QueryBuilderImpl queryBuilder) {
this.queryBuilder = queryBuilder;
public AbstractNode(CriteriaBuilderImpl criteriaBuilder) {
this.criteriaBuilder = criteriaBuilder;
}
/**
* Provides protected access to the underlying {@link QueryBuilderImpl}.
* Provides protected access to the underlying {@link CriteriaBuilderImpl}.
*
* @return The underlying {@link QueryBuilderImpl} instance.
* @return The underlying {@link CriteriaBuilderImpl} instance.
*/
protected QueryBuilderImpl queryBuilder() {
return queryBuilder;
protected CriteriaBuilderImpl queryBuilder() {
return criteriaBuilder;
}
}

View File

@ -39,12 +39,12 @@ public class BasicCollectionJoinImpl<O,E>
implements JoinImplementors.CollectionJoinImplementor<O,E> {
public BasicCollectionJoinImpl(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
Class<E> javaType,
PathImpl<O> lhs,
CollectionAttribute<? super O, E> joinProperty,
JoinType joinType) {
super(queryBuilder, javaType, lhs, joinProperty, joinType);
super( criteriaBuilder, javaType, lhs, joinProperty, joinType);
}
@Override

View File

@ -41,12 +41,12 @@ public class BasicListJoinImpl<O,E>
implements JoinImplementors.ListJoinImplementor<O,E> {
public BasicListJoinImpl(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
Class<E> javaType,
PathImpl<O> lhs,
ListAttribute<? super O, ?> joinProperty,
JoinType joinType) {
super(queryBuilder, javaType, lhs, joinProperty, joinType);
super( criteriaBuilder, javaType, lhs, joinProperty, joinType);
}
@Override
@ -60,7 +60,7 @@ public class BasicListJoinImpl<O,E>
}
public Expression<Integer> index() {
return new ListIndexExpression( queryBuilder(), getAttribute() );
return new ListIndexExpression( queryBuilder(), this, getAttribute() );
}
@Override

View File

@ -50,12 +50,12 @@ public class BasicMapJoinImpl<O,K,V>
public BasicMapJoinImpl(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
Class<V> javaType,
PathImpl<O> lhs,
MapAttribute<? super O, K, V> joinProperty,
JoinType joinType) {
super( queryBuilder, javaType, lhs, joinProperty, joinType );
super( criteriaBuilder, javaType, lhs, joinProperty, joinType );
}
@Override
@ -78,6 +78,7 @@ public class BasicMapJoinImpl<O,K,V>
/**
* {@inheritDoc}
*/
@SuppressWarnings({ "unchecked" })
public Join<Map<K, V>, K> joinKey(JoinType jt) {
if ( PersistenceType.BASIC.equals( getAttribute().getKeyType().getPersistenceType() ) ) {
throw new BasicPathUsageException( "Cannot join to map key of basic type", getAttribute() );
@ -95,14 +96,12 @@ public class BasicMapJoinImpl<O,K,V>
getParentPath().getModel()
);
final MapKeyHelpers.MapKeyAttribute attribute = new MapKeyHelpers.MapKeyAttribute( queryBuilder(), getAttribute() );
final Join<Map<K, V>, K> join = new MapKeyHelpers.MapKeyJoin<K,V>(
return new MapKeyHelpers.MapKeyJoin<K,V>(
queryBuilder(),
source,
attribute,
jt
);
return join;
}
@ -133,13 +132,15 @@ public class BasicMapJoinImpl<O,K,V>
/**
* {@inheritDoc}
*/
@SuppressWarnings({ "unchecked" })
public Expression<Entry<K, V>> entry() {
return new MapKeyHelpers.MapEntryExpression( queryBuilder(), Map.Entry.class, getAttribute() );
return new MapKeyHelpers.MapEntryExpression( queryBuilder(), Map.Entry.class, this, getAttribute() );
}
private From<O, V> correlationParent;
@Override
@SuppressWarnings({ "unchecked" })
public MapJoinImplementor<O, K, V> correlateTo(CriteriaSubqueryImpl subquery) {
BasicMapJoinImpl<O,K,V> correlation = new BasicMapJoinImpl<O,K,V>(
queryBuilder(),

View File

@ -39,12 +39,12 @@ public class BasicSetJoinImpl<O,E>
implements JoinImplementors.SetJoinImplementor<O,E> {
public BasicSetJoinImpl(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
Class<E> javaType,
PathImpl<O> lhs,
SetAttribute<? super O, ?> joinProperty,
JoinType joinType) {
super( queryBuilder, javaType, lhs, joinProperty, joinType );
super( criteriaBuilder, javaType, lhs, joinProperty, joinType );
}
@Override

View File

@ -39,12 +39,12 @@ public class CollectionJoinImpl<O,E>
implements JoinImplementors.CollectionJoinImplementor<O,E> {
public CollectionJoinImpl(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
Class<E> javaType,
PathImpl<O> lhs,
CollectionAttribute<? super O, ?> joinProperty,
JoinType joinType) {
super(queryBuilder, javaType, lhs, joinProperty, joinType);
super( criteriaBuilder, javaType, lhs, joinProperty, joinType);
}
@Override

View File

@ -87,10 +87,10 @@ import static org.hibernate.ejb.criteria.predicate.ComparisonPredicate.Compariso
*
* @author Steve Ebersole
*/
public class QueryBuilderImpl implements CriteriaBuilder, Serializable {
public class CriteriaBuilderImpl implements CriteriaBuilder, Serializable {
private final EntityManagerFactoryImpl entityManagerFactory;
public QueryBuilderImpl(EntityManagerFactoryImpl entityManagerFactory) {
public CriteriaBuilderImpl(EntityManagerFactoryImpl entityManagerFactory) {
this.entityManagerFactory = entityManagerFactory;
}

View File

@ -24,7 +24,17 @@
package org.hibernate.ejb.criteria;
import java.util.Set;
import java.util.Map;
import java.util.HashMap;
import java.util.List;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import javax.persistence.TypedQuery;
import javax.persistence.Parameter;
import javax.persistence.TemporalType;
import javax.persistence.FlushModeType;
import javax.persistence.LockModeType;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.ParameterExpression;
@ -40,6 +50,22 @@ import org.hibernate.ejb.HibernateEntityManagerImplementor;
* @author Steve Ebersole
*/
public class CriteriaQueryCompiler {
public static interface ImplicitParameterBinding {
public void bind(TypedQuery typedQuery);
}
public static interface RenderingContext {
public String generateAlias();
public String generateParameterName();
public void registerExplicitParameter(ParameterExpression<?> criteriaQueryParameter, String jpaqlParameterName);
public void registerImplicitParameterBinding(ImplicitParameterBinding binding);
}
public static interface RenderedCriteriaQuery {
public String getQueryString();
}
private final HibernateEntityManagerImplementor entityManager;
public CriteriaQueryCompiler(HibernateEntityManagerImplementor entityManager) {
@ -48,14 +74,191 @@ public class CriteriaQueryCompiler {
public <T> TypedQuery<T> compile(CriteriaQuery<T> criteriaQuery) {
CriteriaQueryImpl<T> criteriaQueryImpl = ( CriteriaQueryImpl<T> ) criteriaQuery;
criteriaQueryImpl.validate();
Set<ParameterExpression<?>> explicitParameters = criteriaQueryImpl.getParameters();
// todo : implicit parameter handling (handling literal as param, etc).
String jpaqlEquivalent = criteriaQueryImpl.render();
final Map<ParameterExpression<?>,String> explicitParameterMapping = new HashMap<ParameterExpression<?>,String>();
final List<ImplicitParameterBinding> implicitParameterBindings = new ArrayList<ImplicitParameterBinding>();
RenderingContext renderingContext = new RenderingContext() {
private int aliasCount = 0;
private int explicitParameterCount = 0;
public String generateAlias() {
return "generatedAlias" + aliasCount++;
}
public String generateParameterName() {
return "param" + explicitParameterCount++;
}
public void registerExplicitParameter(ParameterExpression<?> criteriaQueryParameter, String jpaqlParameterName) {
explicitParameterMapping.put( criteriaQueryParameter, jpaqlParameterName );
}
public void registerImplicitParameterBinding(ImplicitParameterBinding binding) {
implicitParameterBindings.add( binding );
}
};
RenderedCriteriaQuery renderedCriteriaQuery = criteriaQueryImpl.render( renderingContext );
TypedQuery<T> jpaqlQuery = entityManager.createQuery(
renderedCriteriaQuery.getQueryString(),
criteriaQuery.getResultType()
);
for ( ImplicitParameterBinding implicitParameterBinding : implicitParameterBindings ) {
implicitParameterBinding.bind( jpaqlQuery );
}
return wrap( jpaqlQuery, explicitParameterMapping );
}
private <X> TypedQuery<X> wrap(
final TypedQuery<X> jpaqlQuery,
final Map<ParameterExpression<?>, String> explicitParameterMapping) {
return new TypedQuery<X>() {
public List<X> getResultList() {
return jpaqlQuery.getResultList();
}
public X getSingleResult() {
return jpaqlQuery.getSingleResult();
}
public int getMaxResults() {
return jpaqlQuery.getMaxResults();
}
public TypedQuery<X> setMaxResults(int i) {
return jpaqlQuery.setMaxResults( i );
}
public int getFirstResult() {
return jpaqlQuery.getFirstResult();
}
public TypedQuery<X> setFirstResult(int i) {
return jpaqlQuery.setFirstResult( i );
}
public Map<String, Object> getHints() {
return jpaqlQuery.getHints();
}
public TypedQuery<X> setHint(String name, Object value) {
return jpaqlQuery.setHint( name, value);
}
public FlushModeType getFlushMode() {
return jpaqlQuery.getFlushMode();
}
public TypedQuery<X> setFlushMode(FlushModeType flushModeType) {
return jpaqlQuery.setFlushMode( flushModeType );
}
public LockModeType getLockMode() {
return jpaqlQuery.getLockMode();
}
public TypedQuery<X> setLockMode(LockModeType lockModeType) {
return jpaqlQuery.setLockMode( lockModeType );
}
@SuppressWarnings({ "unchecked" })
public Set getParameters() {
return explicitParameterMapping.keySet();
}
public boolean isBound(Parameter<?> param) {
return jpaqlQuery.isBound( param );
}
@SuppressWarnings({ "unchecked" })
public <T> T getParameterValue(Parameter<T> param) {
return ( T ) jpaqlQuery.getParameterValue( mapToNamedParameter( param ) );
}
@SuppressWarnings({ "unchecked" })
public <T> TypedQuery<X> setParameter(Parameter<T> param, T t) {
return jpaqlQuery.setParameter( mapToNamedParameter( param ), t );
}
@SuppressWarnings({ "RedundantCast" })
private Parameter mapToNamedParameter(Parameter criteriaParameter) {
return jpaqlQuery.getParameter(
explicitParameterMapping.get( (ParameterExpression) criteriaParameter )
);
}
@SuppressWarnings({ "unchecked" })
public TypedQuery<X> setParameter(Parameter<Calendar> param, Calendar calendar, TemporalType temporalType) {
return jpaqlQuery.setParameter( mapToNamedParameter( param ), calendar, temporalType );
}
@SuppressWarnings({ "unchecked" })
public TypedQuery<X> setParameter(Parameter<Date> param, Date date, TemporalType temporalType) {
return jpaqlQuery.setParameter( mapToNamedParameter( param ), date, temporalType );
}
public <T> T unwrap(Class<T> cls) {
return jpaqlQuery.unwrap( cls );
}
// unsupported stuff ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
return null;
public int executeUpdate() {
throw new IllegalArgumentException( "Criteria queries do not support update queries" );
}
public TypedQuery<X> setParameter(String s, Object o) {
throw new IllegalArgumentException( "Criteria queries do not support named parameters" );
}
public TypedQuery<X> setParameter(String s, Calendar calendar, TemporalType temporalType) {
throw new IllegalArgumentException( "Criteria queries do not support named parameters" );
}
public TypedQuery<X> setParameter(String s, Date date, TemporalType temporalType) {
throw new IllegalArgumentException( "Criteria queries do not support named parameters" );
}
public Object getParameterValue(String name) {
throw new IllegalArgumentException( "Criteria queries do not support named parameters" );
}
public Parameter<?> getParameter(String name) {
throw new IllegalArgumentException( "Criteria queries do not support named parameters" );
}
public <T> Parameter<T> getParameter(String name, Class<T> type) {
throw new IllegalArgumentException( "Criteria queries do not support named parameters" );
}
public TypedQuery<X> setParameter(int i, Object o) {
throw new IllegalArgumentException( "Criteria queries do not support positioned parameters" );
}
public TypedQuery<X> setParameter(int i, Calendar calendar, TemporalType temporalType) {
throw new IllegalArgumentException( "Criteria queries do not support positioned parameters" );
}
public TypedQuery<X> setParameter(int i, Date date, TemporalType temporalType) {
throw new IllegalArgumentException( "Criteria queries do not support positioned parameters" );
}
public Object getParameterValue(int position) {
throw new IllegalArgumentException( "Criteria queries do not support positioned parameters" );
}
public Parameter<?> getParameter(int position) {
throw new IllegalArgumentException( "Criteria queries do not support positioned parameters" );
}
public <T> Parameter<T> getParameter(int position, Class<T> type) {
throw new IllegalArgumentException( "Criteria queries do not support positioned parameters" );
}
};
}
}

View File

@ -38,6 +38,8 @@ import javax.persistence.Tuple;
import javax.persistence.criteria.Subquery;
import javax.persistence.metamodel.EntityType;
import org.hibernate.ejb.criteria.expression.ExpressionImplementor;
/**
* The Hibernate implementation of the JPA {@link CriteriaQuery} contract. Mostly a set of delegation to its
* internal {@link QueryStructure}.
@ -52,11 +54,11 @@ public class CriteriaQueryImpl<T> extends AbstractNode implements CriteriaQuery<
public CriteriaQueryImpl(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
Class<T> returnType) {
super( queryBuilder );
super( criteriaBuilder );
this.returnType = returnType;
this.queryStructure = new QueryStructure<T>( this, queryBuilder );
this.queryStructure = new QueryStructure<T>( this, criteriaBuilder );
}
/**
@ -73,7 +75,7 @@ public class CriteriaQueryImpl<T> extends AbstractNode implements CriteriaQuery<
* {@inheritDoc}
*/
public CriteriaQuery<T> distinct(boolean applyDistinction) {
queryStructure.setDistinction( applyDistinction );
queryStructure.setDistinct( applyDistinction );
return this;
}
@ -81,7 +83,7 @@ public class CriteriaQueryImpl<T> extends AbstractNode implements CriteriaQuery<
* {@inheritDoc}
*/
public boolean isDistinct() {
return queryStructure.isDistinction();
return queryStructure.isDistinct();
}
/**
@ -330,7 +332,26 @@ public class CriteriaQueryImpl<T> extends AbstractNode implements CriteriaQuery<
return true;
}
public String render() {
return null;
public CriteriaQueryCompiler.RenderedCriteriaQuery render(CriteriaQueryCompiler.RenderingContext renderingContext) {
final StringBuilder jpaqlQuery = new StringBuilder();
queryStructure.render( jpaqlQuery, renderingContext );
if ( ! getOrderList().isEmpty() ) {
jpaqlQuery.append( " order by " );
String sep = "";
for ( Order orderSpec : getOrderList() ) {
jpaqlQuery.append( sep )
.append( ( ( ExpressionImplementor ) orderSpec.getExpression() ).render( renderingContext ) )
.append( orderSpec.isAscending() ? " asc" : " desc" );
sep = ", ";
}
}
return new CriteriaQueryCompiler.RenderedCriteriaQuery() {
public String getQueryString() {
return jpaqlQuery.toString();
}
};
}
}

View File

@ -26,7 +26,6 @@ package org.hibernate.ejb.criteria;
import java.util.List;
import java.util.Set;
import java.util.HashSet;
import java.util.Collections;
import javax.persistence.criteria.AbstractQuery;
import javax.persistence.criteria.CollectionJoin;
import javax.persistence.criteria.Expression;
@ -76,12 +75,12 @@ public class CriteriaSubqueryImpl<T> extends ExpressionImpl<T> implements Subque
};
public CriteriaSubqueryImpl(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
Class<T> javaType,
AbstractQuery<?> parent) {
super(queryBuilder, javaType);
super( criteriaBuilder, javaType);
this.parent = parent;
this.queryStructure = new QueryStructure<T>( this, queryBuilder );
this.queryStructure = new QueryStructure<T>( this, criteriaBuilder );
}
/**
@ -144,12 +143,12 @@ public class CriteriaSubqueryImpl<T> extends ExpressionImpl<T> implements Subque
// SELECTION ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
public Subquery<T> distinct(boolean applyDistinction) {
queryStructure.setDistinction( applyDistinction );
queryStructure.setDistinct( applyDistinction );
return this;
}
public boolean isDistinct() {
return queryStructure.isDistinction();
return queryStructure.isDistinct();
}
public Expression<T> getSelection() {
@ -298,4 +297,14 @@ public class CriteriaSubqueryImpl<T> extends ExpressionImpl<T> implements Subque
return queryStructure.subquery( subqueryType );
}
public String render(CriteriaQueryCompiler.RenderingContext renderingContext) {
StringBuilder subqueryBuffer = new StringBuilder( "(" );
queryStructure.render( subqueryBuffer, renderingContext );
subqueryBuffer.append( ')' );
return subqueryBuffer.toString();
}
public String renderProjection(CriteriaQueryCompiler.RenderingContext renderingContext) {
throw new IllegalStateException( "Subquery cannot occur in select clause" );
}
}

View File

@ -58,7 +58,7 @@ import org.hibernate.ejb.criteria.expression.EntityTypeExpression;
*
* @author Steve Ebersole
*/
public abstract class FromImpl<Z,X> extends PathImpl<X> implements From<Z,X> {
public abstract class FromImpl<Z,X> extends PathImpl<X> implements From<Z,X>, TableExpressionMapper {
public static final JoinType DEFAULT_JOIN_TYPE = JoinType.INNER;
/**
@ -102,22 +102,33 @@ public abstract class FromImpl<Z,X> extends PathImpl<X> implements From<Z,X> {
/**
* Special constructor for {@link RootImpl}.
*
* @param queryBuilder The query build
* @param criteriaBuilder The query build
* @param entityType The entity defining this root
*/
protected FromImpl(QueryBuilderImpl queryBuilder, EntityType<X> entityType) {
super( queryBuilder, entityType.getBindableJavaType(), null, null, entityType );
this.type = new EntityTypeExpression( queryBuilder, entityType.getBindableJavaType() );
@SuppressWarnings({ "unchecked" })
protected FromImpl(CriteriaBuilderImpl criteriaBuilder, EntityType<X> entityType) {
super( criteriaBuilder, entityType.getBindableJavaType(), null, null, entityType );
this.type = new EntityTypeExpression( criteriaBuilder, entityType.getBindableJavaType() );
}
/**
* The general constructor for a {@link From} implementor.
*
* @param criteriaBuilder
* @param javaType
* @param origin
* @param attribute
* @param model
*/
@SuppressWarnings({ "unchecked" })
public FromImpl(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
Class<X> javaType,
PathImpl<Z> origin,
Attribute<? super Z, ?> attribute,
ManagedType<X> model) {
super( queryBuilder, javaType, origin, attribute, model );
this.type = new EntityTypeExpression( queryBuilder, model.getJavaType() );
super( criteriaBuilder, javaType, origin, attribute, model );
this.type = new EntityTypeExpression( criteriaBuilder, model.getJavaType() );
}
protected void defineJoinScope(JoinScope<X> joinScope) {
@ -341,6 +352,7 @@ public abstract class FromImpl<Z,X> extends PathImpl<X> implements From<Z,X> {
/**
* {@inheritDoc}
*/
@SuppressWarnings({ "unchecked" })
public <X,Y> Join<X, Y> join(String attributeName, JoinType jt) {
if ( jt.equals( JoinType.RIGHT ) ) {
throw new UnsupportedOperationException( "RIGHT JOIN not supported" );
@ -377,6 +389,7 @@ public abstract class FromImpl<Z,X> extends PathImpl<X> implements From<Z,X> {
/**
* {@inheritDoc}
*/
@SuppressWarnings({ "unchecked" })
public <X,Y> CollectionJoin<X, Y> joinCollection(String attributeName, JoinType jt) {
final Attribute<X,?> attribute = (Attribute<X, ?>) getAttribute( attributeName );
if ( ! attribute.isCollection() ) {
@ -401,6 +414,7 @@ public abstract class FromImpl<Z,X> extends PathImpl<X> implements From<Z,X> {
/**
* {@inheritDoc}
*/
@SuppressWarnings({ "unchecked" })
public <X,Y> SetJoin<X, Y> joinSet(String attributeName, JoinType jt) {
final Attribute<X,?> attribute = (Attribute<X, ?>) getAttribute( attributeName );
if ( ! attribute.isCollection() ) {
@ -425,6 +439,7 @@ public abstract class FromImpl<Z,X> extends PathImpl<X> implements From<Z,X> {
/**
* {@inheritDoc}
*/
@SuppressWarnings({ "unchecked" })
public <X,Y> ListJoin<X, Y> joinList(String attributeName, JoinType jt) {
final Attribute<X,?> attribute = (Attribute<X, ?>) getAttribute( attributeName );
if ( ! attribute.isCollection() ) {
@ -449,6 +464,7 @@ public abstract class FromImpl<Z,X> extends PathImpl<X> implements From<Z,X> {
/**
* {@inheritDoc}
*/
@SuppressWarnings({ "unchecked" })
public <X, K, V> MapJoin<X, K, V> joinMap(String attributeName, JoinType jt) {
final Attribute<X,?> attribute = (Attribute<X, ?>) getAttribute( attributeName );
if ( ! attribute.isCollection() ) {
@ -520,6 +536,7 @@ public abstract class FromImpl<Z,X> extends PathImpl<X> implements From<Z,X> {
return fetch( attributeName, DEFAULT_JOIN_TYPE );
}
@SuppressWarnings({ "unchecked" })
public <X,Y> Fetch<X, Y> fetch(String attributeName, JoinType jt) {
Attribute<X,?> attribute = (Attribute<X, ?>) getAttribute( attributeName );
if ( attribute.isCollection() ) {
@ -545,15 +562,17 @@ public abstract class FromImpl<Z,X> extends PathImpl<X> implements From<Z,X> {
@Override
public <E, C extends Collection<E>> Expression<C> get(PluralAttribute<X, C, E> collection) {
return new CollectionExpression<C>( queryBuilder(), collection.getJavaType(), collection );
return new CollectionExpression<C>( queryBuilder(), collection.getJavaType(), this, collection );
}
@Override
@SuppressWarnings({ "unchecked" })
public <K, V, M extends Map<K, V>> Expression<M> get(MapAttribute<X, K, V> map) {
return ( Expression<M> ) new CollectionExpression<Map<K, V>>( queryBuilder(), map.getJavaType(), map );
return ( Expression<M> ) new CollectionExpression<Map<K, V>>( queryBuilder(), map.getJavaType(), this, map );
}
@Override
@SuppressWarnings({ "unchecked" })
public <Y> Path<Y> get(String attributeName) {
Attribute attribute = getAttribute( attributeName );
if ( attribute.isCollection() ) {
@ -575,4 +594,32 @@ public abstract class FromImpl<Z,X> extends PathImpl<X> implements From<Z,X> {
return get( (SingularAttribute<X,Y>) attribute );
}
}
@Override
public String getPathIdentifier() {
return getAlias();
}
@Override
public String render(CriteriaQueryCompiler.RenderingContext renderingContext) {
prepareAlias( renderingContext );
return getAlias();
}
@Override
public String renderProjection(CriteriaQueryCompiler.RenderingContext renderingContext) {
prepareAlias( renderingContext );
return getAlias();
}
public String renderTableExpression(CriteriaQueryCompiler.RenderingContext renderingContext) {
prepareAlias( renderingContext );
return ( (EntityType) getModel() ).getName() + " as " + getAlias();
}
public void prepareAlias(CriteriaQueryCompiler.RenderingContext renderingContext) {
if ( getAlias() == null ) {
setAlias( renderingContext.generateAlias() );
}
}
}

View File

@ -44,18 +44,19 @@ public class JoinImpl<Z, X> extends FromImpl<Z, X> implements JoinImplementors.J
private final ManagedType<X> managedType;
private final JoinType joinType;
@SuppressWarnings({ "unchecked" })
public JoinImpl(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
Class<X> javaType,
PathImpl<Z> lhs,
Attribute<? super Z, ?> joinProperty,
JoinType joinType) {
super(
queryBuilder,
criteriaBuilder,
javaType,
lhs,
joinProperty,
(ManagedType<X>)queryBuilder.getEntityManagerFactory().getMetamodel().managedType( javaType )
(ManagedType<X>) criteriaBuilder.getEntityManagerFactory().getMetamodel().managedType( javaType )
);
this.managedType = (ManagedType<X>) getModel();
this.joinType = joinType;
@ -64,12 +65,14 @@ public class JoinImpl<Z, X> extends FromImpl<Z, X> implements JoinImplementors.J
/**
* {@inheritDoc}
*/
@SuppressWarnings({ "unchecked" })
public From<?, Z> getParent() {
// AFAICT, only "froms" (specifically roots and joins) can be the parent of a join.
return ( From<?, Z> ) getParentPath();
}
@Override
@SuppressWarnings({ "unchecked" })
public Attribute<? super Z, ?> getAttribute() {
return (Attribute<? super Z, ?>) super.getAttribute();
}
@ -82,10 +85,12 @@ public class JoinImpl<Z, X> extends FromImpl<Z, X> implements JoinImplementors.J
}
@Override
@SuppressWarnings({ "unchecked" })
protected Attribute<X, ?> getAttribute(String name) {
return (Attribute<X, ?>) managedType.getAttribute( name );
}
@SuppressWarnings({ "unchecked" })
public JoinImplementors.JoinImplementor<Z,X> correlateTo(CriteriaSubqueryImpl subquery) {
JoinImpl<Z,X> correlation = new JoinImpl<Z,X>(
queryBuilder(),
@ -112,7 +117,12 @@ public class JoinImpl<Z, X> extends FromImpl<Z, X> implements JoinImplementors.J
* {@inheritDoc}
*/
public From<Z,X> getCorrelationParent() {
return null;
return correlationParent;
}
public String renderTableExpression(CriteriaQueryCompiler.RenderingContext renderingContext) {
prepareAlias( renderingContext );
( (FromImpl) getParent() ).prepareAlias( renderingContext );
return getParent().getAlias() + '.' + getAttribute().getName() + " as " + getAlias();
}
}

View File

@ -38,12 +38,12 @@ import org.hibernate.ejb.criteria.expression.ListIndexExpression;
*/
public class ListJoinImpl<O,E> extends JoinImpl<O,E> implements JoinImplementors.ListJoinImplementor<O,E> {
public ListJoinImpl(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
Class<E> javaType,
PathImpl<O> lhs,
ListAttribute<? super O, ?> joinProperty,
JoinType joinType) {
super( queryBuilder, javaType, lhs, joinProperty, joinType );
super( criteriaBuilder, javaType, lhs, joinProperty, joinType );
}
@Override
@ -60,7 +60,7 @@ public class ListJoinImpl<O,E> extends JoinImpl<O,E> implements JoinImplementors
* {@inheritDoc}
*/
public Expression<Integer> index() {
return new ListIndexExpression( queryBuilder(), getAttribute() );
return new ListIndexExpression( queryBuilder(), this, getAttribute() );
}
@Override

View File

@ -45,12 +45,12 @@ public class MapJoinImpl<O,K,V>
implements JoinImplementors.MapJoinImplementor<O,K,V> {
public MapJoinImpl(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
Class<V> javaType,
PathImpl<O> lhs,
MapAttribute<? super O, K, V> joinProperty,
JoinType joinType) {
super(queryBuilder, javaType, lhs, joinProperty, joinType);
super( criteriaBuilder, javaType, lhs, joinProperty, joinType);
}
@Override
@ -73,6 +73,7 @@ public class MapJoinImpl<O,K,V>
/**
* {@inheritDoc}
*/
@SuppressWarnings({ "unchecked" })
public Join<Map<K, V>, K> joinKey(JoinType jt) {
if ( PersistenceType.BASIC.equals( getAttribute().getKeyType().getPersistenceType() ) ) {
throw new BasicPathUsageException( "Cannot join to map key of basic type", getAttribute() );
@ -90,19 +91,18 @@ public class MapJoinImpl<O,K,V>
getParentPath().getModel()
);
final MapKeyHelpers.MapKeyAttribute mapKeyAttribute = new MapKeyHelpers.MapKeyAttribute( queryBuilder(), getAttribute() );
final Join<Map<K, V>, K> join = new MapKeyHelpers.MapKeyJoin<K,V>(
return new MapKeyHelpers.MapKeyJoin<K,V>(
queryBuilder(),
mapKeySource,
mapKeyAttribute,
jt
);
return join;
}
/**
* {@inheritDoc}
*/
@SuppressWarnings({ "unchecked" })
public Path<K> key() {
final MapKeyHelpers.MapPath<K,V> mapKeySource = new MapKeyHelpers.MapPath<K,V>(
queryBuilder(),
@ -125,14 +125,16 @@ public class MapJoinImpl<O,K,V>
/**
* {@inheritDoc}
*/
@SuppressWarnings({ "unchecked" })
public Expression<Entry<K, V>> entry() {
return new MapKeyHelpers.MapEntryExpression( queryBuilder(), Map.Entry.class, getAttribute() );
return new MapKeyHelpers.MapEntryExpression( queryBuilder(), Map.Entry.class, this, getAttribute() );
}
private From<O, V> correlationParent;
@Override
@SuppressWarnings({ "unchecked" })
public MapJoinImplementor<O, K, V> correlateTo(CriteriaSubqueryImpl subquery) {
MapJoinImpl<O, K, V> correlation = new MapJoinImpl<O, K, V>(
queryBuilder(),

View File

@ -33,13 +33,13 @@ import javax.persistence.criteria.MapJoin;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.From;
import javax.persistence.metamodel.Attribute;
import javax.persistence.metamodel.Bindable.BindableType;
import javax.persistence.metamodel.ManagedType;
import javax.persistence.metamodel.MapAttribute;
import javax.persistence.metamodel.SingularAttribute;
import javax.persistence.metamodel.Type.PersistenceType;
import org.hibernate.ejb.criteria.JoinImplementors.JoinImplementor;
import org.hibernate.ejb.criteria.expression.ExpressionImpl;
import org.hibernate.ejb.criteria.expression.ExpressionImplementor;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.type.Type;
@ -61,9 +61,9 @@ public class MapKeyHelpers {
* @param <V> The type of the map value
*/
public static class MapKeyJoin<K,V> extends JoinImpl<Map<K, V>, K> implements Join<Map<K, V>, K> {
public MapKeyJoin(QueryBuilderImpl queryBuilder, MapPath<K,V> source, MapKeyAttribute<K> attribute, JoinType jt) {
public MapKeyJoin(CriteriaBuilderImpl criteriaBuilder, MapPath<K,V> source, MapKeyAttribute<K> attribute, JoinType jt) {
super(
queryBuilder,
criteriaBuilder,
attribute.getJavaType(),
source,
attribute,
@ -92,10 +92,10 @@ public class MapKeyHelpers {
*/
public static class MapKeyPath<K> extends PathImpl<K> implements Path<K> {
public MapKeyPath(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
MapPath<K,?> source,
MapKeyAttribute<K> attribute) {
super( queryBuilder, attribute.getJavaType(), source, attribute, attribute.getType() );
super( criteriaBuilder, attribute.getJavaType(), source, attribute, attribute.getType() );
}
}
@ -110,12 +110,12 @@ public class MapKeyHelpers {
private final MapJoin<?,K,V> mapJoin;
public MapPath(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
Class<Map<K, V>> javaType,
MapJoin<?,K,V> mapJoin,
MapAttribute<?,K,V> attribute,
Object model) {
super(queryBuilder, javaType, null, attribute, model);
super( criteriaBuilder, javaType, null, attribute, model);
this.mapJoin = mapJoin;
}
@ -146,7 +146,7 @@ public class MapKeyHelpers {
private final BindableType jpaBindableType;
private final Class<K> jpaBinableJavaType;
public MapKeyAttribute(QueryBuilderImpl queryBuilder, MapAttribute<?, K, ?> attribute) {
public MapKeyAttribute(CriteriaBuilderImpl criteriaBuilder, MapAttribute<?, K, ?> attribute) {
this.attribute = attribute;
this.jpaType = attribute.getKeyType();
this.jpaBinableJavaType = attribute.getKeyJavaType();
@ -156,7 +156,7 @@ public class MapKeyHelpers {
String guessedRoleName = determineRole( attribute );
SessionFactoryImplementor sfi = (SessionFactoryImplementor)
queryBuilder.getEntityManagerFactory().getSessionFactory();
criteriaBuilder.getEntityManagerFactory().getSessionFactory();
mapPersister = sfi.getCollectionPersister( guessedRoleName );
if ( mapPersister == null ) {
throw new IllegalStateException( "Could not locate collection persister [" + guessedRoleName + "]" );
@ -260,13 +260,16 @@ public class MapKeyHelpers {
public static class MapEntryExpression<K,V>
extends ExpressionImpl<Map.Entry<K,V>>
implements Expression<Map.Entry<K,V>> {
private final PathImpl origin;
private final MapAttribute<?, K, V> attribute;
public MapEntryExpression(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
Class<Entry<K, V>> javaType,
PathImpl origin,
MapAttribute<?, K, V> attribute) {
super(queryBuilder, javaType);
super( criteriaBuilder, javaType);
this.origin = origin;
this.attribute = attribute;
}
@ -278,6 +281,20 @@ public class MapKeyHelpers {
// none to register
}
public String render(CriteriaQueryCompiler.RenderingContext renderingContext) {
// i dont think this is vqalid outside of select clause...
throw new IllegalStateException( "illegal reference to map entry outside of select clause." );
}
public String renderProjection(CriteriaQueryCompiler.RenderingContext renderingContext) {
return "entry(" + path( renderingContext ) + ")";
}
private String path(CriteriaQueryCompiler.RenderingContext renderingContext) {
return origin.getPathIdentifier()
+ '.'
+ ( (ExpressionImplementor) getAttribute() ).renderProjection( renderingContext );
}
}
/**

View File

@ -48,19 +48,19 @@ public class PathImpl<X> extends ExpressionImpl<X> implements Path<X> {
/**
* Constructs a path.
*
* @param queryBuilder The delegate for building query components.
* @param criteriaBuilder The delegate for building query components.
* @param javaType The java type of this path,
* @param origin The source ("lhs") of this path.
* @param attribute The attribute defining this path element.
* @param model The corresponding model of this path.
*/
protected PathImpl(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
Class<X> javaType,
PathImpl<?> origin,
Attribute<?,?> attribute,
Object model) {
super( queryBuilder, javaType );
super( criteriaBuilder, javaType );
this.origin = origin;
this.attribute = attribute;
this.model = model;
@ -80,7 +80,8 @@ public class PathImpl<X> extends ExpressionImpl<X> implements Path<X> {
/**
* {@inheritDoc}
*/
public Bindable<X> getModel() {
@SuppressWarnings({ "unchecked" })
public Bindable<X> getModel() {
if ( model == null ) {
throw new IllegalStateException( this + " represents a basic path and not a bindable" );
}
@ -145,4 +146,24 @@ public class PathImpl<X> extends ExpressionImpl<X> implements Path<X> {
// none to register
}
/**
* 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() {
return getParentPath().getPathIdentifier() + "." + getAttribute().getName();
}
public String render(CriteriaQueryCompiler.RenderingContext renderingContext) {
( (TableExpressionMapper) getParentPath() ).prepareAlias( renderingContext );
return getParentPath().getAlias()
+ '.'
+ getAttribute().getName();
}
public String renderProjection(CriteriaQueryCompiler.RenderingContext renderingContext) {
return render( renderingContext );
}
}

View File

@ -30,6 +30,7 @@ import java.util.List;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.ArrayList;
import java.util.Collection;
import javax.persistence.criteria.AbstractQuery;
import javax.persistence.criteria.Root;
import javax.persistence.criteria.Predicate;
@ -37,8 +38,13 @@ import javax.persistence.criteria.Expression;
import javax.persistence.criteria.ParameterExpression;
import javax.persistence.criteria.Selection;
import javax.persistence.criteria.Subquery;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.Fetch;
import javax.persistence.criteria.JoinType;
import javax.persistence.metamodel.EntityType;
import org.hibernate.ejb.criteria.expression.ExpressionImplementor;
/**
* Models basic query structure. Used as a delegate in implementing both
* {@link org.hibernate.criterion.CriteriaQuery} and
@ -52,14 +58,14 @@ import javax.persistence.metamodel.EntityType;
*/
public class QueryStructure<T> {
private final AbstractQuery<T> owner;
private final QueryBuilderImpl queryBuilder;
private final CriteriaBuilderImpl criteriaBuilder;
public QueryStructure(AbstractQuery<T> owner, QueryBuilderImpl queryBuilder) {
public QueryStructure(AbstractQuery<T> owner, CriteriaBuilderImpl criteriaBuilder) {
this.owner = owner;
this.queryBuilder = queryBuilder;
this.criteriaBuilder = criteriaBuilder;
}
private boolean distinction;
private boolean distinct;
private Selection<? extends T> selection;
private Set<Root<?>> roots = new HashSet<Root<?>>();
private Predicate restriction;
@ -101,12 +107,12 @@ public class QueryStructure<T> {
// SELECTION ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
public boolean isDistinction() {
return distinction;
public boolean isDistinct() {
return distinct;
}
public void setDistinction(boolean distinction) {
this.distinction = distinction;
public void setDistinct(boolean distinct) {
this.distinct = distinct;
}
public Selection<? extends T> getSelection() {
@ -125,7 +131,7 @@ public class QueryStructure<T> {
}
public <X> Root<X> from(Class<X> entityClass) {
EntityType<X> entityType = queryBuilder.getEntityManagerFactory()
EntityType<X> entityType = criteriaBuilder.getEntityManagerFactory()
.getMetamodel()
.entity( entityClass );
if ( entityType == null ) {
@ -135,7 +141,7 @@ public class QueryStructure<T> {
}
public <X> Root<X> from(EntityType<X> entityType) {
RootImpl<X> root = new RootImpl<X>( queryBuilder, entityType );
RootImpl<X> root = new RootImpl<X>( criteriaBuilder, entityType );
roots.add( root );
return root;
}
@ -194,8 +200,111 @@ public class QueryStructure<T> {
}
public <U> Subquery<U> subquery(Class<U> subqueryType) {
CriteriaSubqueryImpl<U> subquery = new CriteriaSubqueryImpl<U>( queryBuilder, subqueryType, owner );
CriteriaSubqueryImpl<U> subquery = new CriteriaSubqueryImpl<U>( criteriaBuilder, subqueryType, owner );
internalGetSubqueries().add( subquery );
return subquery;
}
@SuppressWarnings({ "unchecked" })
public void render(StringBuilder jpaqlQuery, CriteriaQueryCompiler.RenderingContext renderingContext) {
jpaqlQuery.append( "select " );
if ( isDistinct() ) {
jpaqlQuery.append( " distinct " );
}
if ( getSelection() == null ) {
// we should have only a single root (query validation should have checked this...)
final Root root = getRoots().iterator().next();
( (TableExpressionMapper) root ).prepareAlias( renderingContext );
jpaqlQuery.append( root.getAlias() );
}
else {
( ( ExpressionImplementor ) getSelection() ).renderProjection( renderingContext );
}
jpaqlQuery.append( " from " );
String sep = "";
for ( Root root : getRoots() ) {
( (TableExpressionMapper) root ).prepareAlias( renderingContext );
jpaqlQuery.append( sep );
jpaqlQuery.append( ( ( TableExpressionMapper ) root ).renderTableExpression( renderingContext ) );
sep = ", ";
}
for ( Root root : getRoots() ) {
renderJoins( jpaqlQuery, renderingContext, root.getJoins() );
renderFetches( jpaqlQuery, renderingContext, root.getFetches() );
}
if ( getRestriction() != null) {
jpaqlQuery.append( " where " )
.append( ( (ExpressionImplementor) getRestriction() ).render( renderingContext ) );
}
if ( ! getGroupings().isEmpty() ) {
jpaqlQuery.append( " group by " );
sep = "";
for ( Expression grouping : getGroupings() ) {
jpaqlQuery.append( sep )
.append( ( (ExpressionImplementor) grouping ).render( renderingContext ) );
sep = ", ";
}
if ( getHaving() != null ) {
jpaqlQuery.append( " having " )
.append( ( (ExpressionImplementor) getHaving() ).render( renderingContext ) );
}
}
}
@SuppressWarnings({ "unchecked" })
private void renderJoins(
StringBuilder jpaqlQuery,
CriteriaQueryCompiler.RenderingContext renderingContext,
Collection<Join<?,?>> joins) {
if ( joins == null ) {
return;
}
for ( Join join : joins ) {
( (TableExpressionMapper) join ).prepareAlias( renderingContext );
jpaqlQuery.append( renderJoinType( join.getJoinType() ) )
.append( ( ( TableExpressionMapper ) join ).renderTableExpression( renderingContext ) );
renderJoins( jpaqlQuery, renderingContext, join.getJoins() );
renderFetches( jpaqlQuery, renderingContext, join.getFetches() );
}
}
private String renderJoinType(JoinType joinType) {
switch ( joinType ) {
case INNER: {
return " inner join ";
}
case LEFT: {
return " left join ";
}
case RIGHT: {
return " right join ";
}
}
throw new IllegalStateException( "Unknown join type " + joinType );
}
@SuppressWarnings({ "unchecked" })
private void renderFetches(
StringBuilder jpaqlQuery,
CriteriaQueryCompiler.RenderingContext renderingContext,
Collection<Fetch> fetches) {
if ( fetches == null ) {
return;
}
for ( Fetch fetch : fetches ) {
( (TableExpressionMapper) fetch ).prepareAlias( renderingContext );
jpaqlQuery.append( renderJoinType( fetch.getJoinType() ) )
.append( "fetch " )
.append( ( ( TableExpressionMapper ) fetch ).renderTableExpression( renderingContext ) );
renderFetches( jpaqlQuery, renderingContext, fetch.getFetches() );
}
}
}

View File

@ -37,9 +37,9 @@ public class RootImpl<X> extends FromImpl<X,X> implements Root<X> {
private RootImpl<X> correlationParent;
public RootImpl(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
EntityType<X> model) {
super( queryBuilder, model );
super( criteriaBuilder, model );
}
@Override

View File

@ -39,12 +39,12 @@ public class SetJoinImpl<O,E>
implements JoinImplementors.SetJoinImplementor<O,E> {
public SetJoinImpl(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
Class<E> javaType,
PathImpl<O> lhs,
SetAttribute<? super O, ?> joinProperty,
JoinType joinType) {
super(queryBuilder, javaType, lhs, joinProperty, joinType);
super( criteriaBuilder, javaType, lhs, joinProperty, joinType);
}
@Override

View File

@ -0,0 +1,34 @@
/*
* 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;
/**
* Common contract for things which map to a table expression in a <tt>SQL FROM clause</tt>.
*
* @author Steve Ebersole
*/
public interface TableExpressionMapper {
public void prepareAlias(CriteriaQueryCompiler.RenderingContext renderingContext);
public String renderTableExpression(CriteriaQueryCompiler.RenderingContext renderingContext);
}

View File

@ -26,7 +26,7 @@ package org.hibernate.ejb.criteria.expression;
import javax.persistence.TupleElement;
import org.hibernate.ejb.criteria.AbstractNode;
import org.hibernate.ejb.criteria.QueryBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
/**
* TODO : javadoc
@ -37,8 +37,8 @@ public abstract class AbstractTupleElement<X> extends AbstractNode implements Tu
private final Class<X> javaType;
private String alias;
protected AbstractTupleElement(QueryBuilderImpl queryBuilder, Class<X> javaType) {
super( queryBuilder );
protected AbstractTupleElement(CriteriaBuilderImpl criteriaBuilder, Class<X> javaType) {
super( criteriaBuilder );
this.javaType = javaType;
}

View File

@ -26,7 +26,8 @@ package org.hibernate.ejb.criteria.expression;
import javax.persistence.criteria.Expression;
import org.hibernate.ejb.criteria.ParameterRegistry;
import org.hibernate.ejb.criteria.QueryBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaQueryCompiler;
/**
* Models standard arithmetc operations with two operands.
@ -38,7 +39,37 @@ public class BinaryArithmeticOperation<N extends Number>
implements BinaryOperatorExpression<N> {
public static enum Operation {
ADD, SUBTRACT, MULTIPLY, DIVIDE, QUOT, MOD
ADD {
String apply(String lhs, String rhs) {
return lhs + " + " + rhs;
}
},
SUBTRACT {
String apply(String lhs, String rhs) {
return lhs + " - " + rhs;
}
},
MULTIPLY {
String apply(String lhs, String rhs) {
return lhs + " * " + rhs;
}
},
DIVIDE {
String apply(String lhs, String rhs) {
return lhs + " / " + rhs;
}
},
QUOT {
String apply(String lhs, String rhs) {
return lhs + " / " + rhs;
}
},
MOD {
String apply(String lhs, String rhs) {
return lhs + " % " + rhs;
}
};
abstract String apply(String lhs, String rhs);
}
private final Operation operator;
@ -78,19 +109,19 @@ public class BinaryArithmeticOperation<N extends Number>
/**
* Creates an arithmethic operation based on 2 expressions.
*
* @param queryBuilder The builder for query components.
* @param criteriaBuilder The builder for query components.
* @param resultType The operation result type
* @param operator The operator (type of operation).
* @param rhs The right-hand operand
* @param lhs The left-hand operand.
*/
public BinaryArithmeticOperation(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
Class<N> resultType,
Operation operator,
Expression<? extends N> rhs,
Expression<? extends N> lhs) {
super( queryBuilder, resultType );
super( criteriaBuilder, resultType );
this.operator = operator;
this.rhs = rhs;
this.lhs = lhs;
@ -99,42 +130,42 @@ public class BinaryArithmeticOperation<N extends Number>
/**
* Creates an arithmethic operation based on an expression and a literal.
*
* @param queryBuilder The builder for query components.
* @param resultType The operation result type
* @param criteriaBuilder The builder for query components.
* @param javaType The operation result type
* @param operator The operator (type of operation).
* @param rhs The right-hand operand
* @param lhs The left-hand operand (the literal).
*/
public BinaryArithmeticOperation(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
Class<N> javaType,
Operation operator,
Expression<? extends N> rhs,
N lhs) {
super( queryBuilder, javaType );
super( criteriaBuilder, javaType );
this.operator = operator;
this.rhs = rhs;
this.lhs = new LiteralExpression<N>( queryBuilder, lhs );
this.lhs = new LiteralExpression<N>( criteriaBuilder, lhs );
}
/**
* Creates an arithmethic operation based on an expression and a literal.
*
* @param queryBuilder The builder for query components.
* @param resultType The operation result type
* @param criteriaBuilder The builder for query components.
* @param javaType The operation result type
* @param operator The operator (type of operation).
* @param rhs The right-hand operand (the literal).
* @param lhs The left-hand operand
*/
public BinaryArithmeticOperation(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
Class<N> javaType,
Operation operator,
N rhs,
Expression<? extends N> lhs) {
super( queryBuilder, javaType );
super( criteriaBuilder, javaType );
this.operator = operator;
this.rhs = new LiteralExpression<N>( queryBuilder, rhs );
this.rhs = new LiteralExpression<N>( criteriaBuilder, rhs );
this.lhs = lhs;
}
public Operation getOperator() {
@ -163,4 +194,14 @@ public class BinaryArithmeticOperation<N extends Number>
Helper.possibleParameter( getLeftHandOperand(), registry );
}
public String render(CriteriaQueryCompiler.RenderingContext renderingContext) {
return getOperator().apply(
( (ExpressionImplementor) getLeftHandOperand() ).render( renderingContext ),
( (ExpressionImplementor) getRightHandOperand() ).render( renderingContext )
);
}
public String renderProjection(CriteriaQueryCompiler.RenderingContext renderingContext) {
return render( renderingContext );
}
}

View File

@ -28,7 +28,8 @@ import java.util.List;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.CriteriaBuilder.Coalesce;
import org.hibernate.ejb.criteria.ParameterRegistry;
import org.hibernate.ejb.criteria.QueryBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaQueryCompiler;
/**
* Models an ANSI SQL <tt>COALESCE</tt> expression. <tt>COALESCE</tt> is a specialized <tt>CASE</tt> statement.
@ -39,14 +40,14 @@ public class CoalesceExpression<T> extends ExpressionImpl<T> implements Coalesce
private final List<Expression<? extends T>> expressions;
private Class<T> javaType;
public CoalesceExpression(QueryBuilderImpl queryBuilder) {
this( queryBuilder, null );
public CoalesceExpression(CriteriaBuilderImpl criteriaBuilder) {
this( criteriaBuilder, null );
}
public CoalesceExpression(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
Class<T> javaType) {
super( queryBuilder, javaType );
super( criteriaBuilder, javaType );
this.javaType = javaType;
this.expressions = new ArrayList<Expression<? extends T>>();
}
@ -79,5 +80,18 @@ public class CoalesceExpression<T> extends ExpressionImpl<T> implements Coalesce
}
}
public String render(CriteriaQueryCompiler.RenderingContext renderingContext) {
StringBuilder buffer = new StringBuilder( "coalesce(" );
String sep = "";
for ( Expression expression : getExpressions() ) {
buffer.append( sep )
.append( ( (ExpressionImplementor) expression ).render( renderingContext ) );
sep = ", ";
}
return buffer.append( ")" ).toString();
}
public String renderProjection(CriteriaQueryCompiler.RenderingContext renderingContext) {
return render( renderingContext );
}
}

View File

@ -25,7 +25,9 @@ package org.hibernate.ejb.criteria.expression;
import javax.persistence.metamodel.PluralAttribute;
import org.hibernate.ejb.criteria.ParameterRegistry;
import org.hibernate.ejb.criteria.QueryBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
import org.hibernate.ejb.criteria.PathImpl;
import org.hibernate.ejb.criteria.CriteriaQueryCompiler;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.persister.collection.CollectionPersister;
@ -35,19 +37,21 @@ import org.hibernate.persister.collection.CollectionPersister;
* @author Steve Ebersole
*/
public class CollectionExpression<C> extends ExpressionImpl<C> {
private final PathImpl origin;
private final CollectionPersister persister;
private final PluralAttribute<?, C, ?> attribute;
public CollectionExpression(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
Class<C> javaType,
PathImpl origin,
PluralAttribute<?, C, ?> attribute) {
this( queryBuilder, javaType, resolvePersister( queryBuilder, attribute ), attribute );
this( criteriaBuilder, javaType, resolvePersister( criteriaBuilder, attribute ), origin, attribute );
}
private static CollectionPersister resolvePersister(QueryBuilderImpl queryBuilder, PluralAttribute attribute) {
private static CollectionPersister resolvePersister(CriteriaBuilderImpl criteriaBuilder, PluralAttribute attribute) {
SessionFactoryImplementor sfi = (SessionFactoryImplementor)
queryBuilder.getEntityManagerFactory().getSessionFactory();
criteriaBuilder.getEntityManagerFactory().getSessionFactory();
return sfi.getCollectionPersister( resolveRole( attribute ) );
}
@ -57,11 +61,13 @@ public class CollectionExpression<C> extends ExpressionImpl<C> {
}
public CollectionExpression(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
Class<C> javaType,
CollectionPersister persister,
PathImpl origin,
PluralAttribute<?, C, ?> attribute) {
super(queryBuilder, javaType);
super( criteriaBuilder, javaType );
this.origin = origin;
this.persister = persister;
this.attribute = attribute;
}
@ -77,4 +83,12 @@ public class CollectionExpression<C> extends ExpressionImpl<C> {
public void registerParameters(ParameterRegistry registry) {
// none to register
}
public String render(CriteriaQueryCompiler.RenderingContext renderingContext) {
return origin.getPathIdentifier() + '.' + getAttribute().getName();
}
public String renderProjection(CriteriaQueryCompiler.RenderingContext renderingContext) {
return render( renderingContext );
}
}

View File

@ -27,9 +27,8 @@ import java.util.List;
import javax.persistence.criteria.CompoundSelection;
import javax.persistence.criteria.Selection;
import org.hibernate.ejb.criteria.ParameterContainer;
import org.hibernate.ejb.criteria.ParameterRegistry;
import org.hibernate.ejb.criteria.QueryBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
/**
* The Hibernate implementation of the JPA {@link CompoundSelection}
@ -41,10 +40,10 @@ public class CompoundSelectionImpl<X> extends SelectionImpl<X> implements Compou
private List<Selection<?>> selectionItems;
public CompoundSelectionImpl(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
Class<X> javaType,
List<Selection<?>> selectionItems) {
super( queryBuilder, javaType );
super( criteriaBuilder, javaType );
this.selectionItems = selectionItems;
}

View File

@ -24,12 +24,12 @@
package org.hibernate.ejb.criteria.expression;
import javax.persistence.criteria.Expression;
import org.hibernate.ejb.criteria.ParameterContainer;
import org.hibernate.ejb.criteria.ParameterRegistry;
import org.hibernate.ejb.criteria.QueryBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaQueryCompiler;
/**
* TODO : javadoc
* A string concatenation.
*
* @author Steve Ebersole
*/
@ -38,30 +38,30 @@ public class ConcatExpression extends ExpressionImpl<String> {
private Expression<String> string2;
public ConcatExpression(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
Expression<String> expression1,
Expression<String> expression2) {
super( queryBuilder, String.class );
super( criteriaBuilder, String.class );
this.string1 = expression1;
this.string2 = expression2;
}
public ConcatExpression(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
Expression<String> string1,
String string2) {
this( queryBuilder, string1, wrap(queryBuilder, string2) );
this( criteriaBuilder, string1, wrap( criteriaBuilder, string2) );
}
private static Expression<String> wrap(QueryBuilderImpl queryBuilder, String string) {
return new LiteralExpression<String>( queryBuilder, string );
private static Expression<String> wrap(CriteriaBuilderImpl criteriaBuilder, String string) {
return new LiteralExpression<String>( criteriaBuilder, string );
}
public ConcatExpression(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
String string1,
Expression<String> string2) {
this( queryBuilder, wrap(queryBuilder, string1), string2 );
this( criteriaBuilder, wrap( criteriaBuilder, string1), string2 );
}
public Expression<String> getString1() {
@ -77,4 +77,13 @@ public class ConcatExpression extends ExpressionImpl<String> {
Helper.possibleParameter( getString2(), registry );
}
public String render(CriteriaQueryCompiler.RenderingContext renderingContext) {
return ( (ExpressionImplementor) getString1() ).render( renderingContext )
+ " || "
+ ( (ExpressionImplementor) getString2() ).render( renderingContext );
}
public String renderProjection(CriteriaQueryCompiler.RenderingContext renderingContext) {
return render( renderingContext );
}
}

View File

@ -24,7 +24,8 @@
package org.hibernate.ejb.criteria.expression;
import org.hibernate.ejb.criteria.ParameterRegistry;
import org.hibernate.ejb.criteria.QueryBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaQueryCompiler;
/**
* TODO : javadoc
@ -32,12 +33,20 @@ import org.hibernate.ejb.criteria.QueryBuilderImpl;
* @author Steve Ebersole
*/
public class EntityTypeExpression<T> extends ExpressionImpl<T> {
public EntityTypeExpression(QueryBuilderImpl queryBuilder, Class<T> javaType) {
super( queryBuilder, javaType );
public EntityTypeExpression(CriteriaBuilderImpl criteriaBuilder, Class<T> javaType) {
super( criteriaBuilder, javaType );
}
public void registerParameters(ParameterRegistry registry) {
// nothign to do
}
public String render(CriteriaQueryCompiler.RenderingContext renderingContext) {
// todo : is it valid for this to get rendered into the query itself?
throw new IllegalArgumentException( "Unexpected call on EntityTypeExpression#render" );
}
public String renderProjection(CriteriaQueryCompiler.RenderingContext renderingContext) {
return render( renderingContext );
}
}

View File

@ -27,7 +27,7 @@ import java.util.Collection;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Predicate;
import org.hibernate.ejb.criteria.QueryBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
import org.hibernate.ejb.criteria.expression.function.CastFunction;
/**
@ -35,9 +35,9 @@ import org.hibernate.ejb.criteria.expression.function.CastFunction;
*
* @author Steve Ebersole
*/
public abstract class ExpressionImpl<T> extends SelectionImpl<T> implements Expression<T> {
public ExpressionImpl(QueryBuilderImpl queryBuilder, Class<T> javaType) {
super( queryBuilder, javaType );
public abstract class ExpressionImpl<T> extends SelectionImpl<T> implements ExpressionImplementor<T> {
public ExpressionImpl(CriteriaBuilderImpl criteriaBuilder, Class<T> javaType) {
super( criteriaBuilder, javaType );
}
/**

View File

@ -0,0 +1,38 @@
/*
* 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.expression;
import javax.persistence.criteria.Expression;
import org.hibernate.ejb.criteria.CriteriaQueryCompiler;
/**
* TODO : javadoc
*
* @author Steve Ebersole
*/
public interface ExpressionImplementor<T> extends Expression<T> {
public String render(CriteriaQueryCompiler.RenderingContext renderingContext);
public String renderProjection(CriteriaQueryCompiler.RenderingContext renderingContext);
}

View File

@ -25,7 +25,9 @@ package org.hibernate.ejb.criteria.expression;
import javax.persistence.metamodel.ListAttribute;
import org.hibernate.ejb.criteria.ParameterRegistry;
import org.hibernate.ejb.criteria.QueryBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaQueryCompiler;
import org.hibernate.ejb.criteria.PathImpl;
/**
* An expression for referring to the index of a list.
@ -33,10 +35,12 @@ import org.hibernate.ejb.criteria.QueryBuilderImpl;
* @author Steve Ebersole
*/
public class ListIndexExpression extends ExpressionImpl<Integer> {
private final PathImpl origin;
private final ListAttribute<?,?> listAttribute;
public ListIndexExpression(QueryBuilderImpl queryBuilder, ListAttribute<?,?> listAttribute) {
super( queryBuilder, Integer.class );
public ListIndexExpression(CriteriaBuilderImpl criteriaBuilder, PathImpl origin, ListAttribute<?,?> listAttribute) {
super( criteriaBuilder, Integer.class );
this.origin = origin;
this.listAttribute = listAttribute;
}
@ -47,4 +51,14 @@ public class ListIndexExpression extends ExpressionImpl<Integer> {
public void registerParameters(ParameterRegistry registry) {
// nothign to do
}
public String render(CriteriaQueryCompiler.RenderingContext renderingContext) {
return "index("
+ origin.getPathIdentifier() + '.' + getListAttribute().getName()
+ ")";
}
public String renderProjection(CriteriaQueryCompiler.RenderingContext renderingContext) {
return render( renderingContext );
}
}

View File

@ -23,8 +23,11 @@
*/
package org.hibernate.ejb.criteria.expression;
import javax.persistence.TypedQuery;
import org.hibernate.ejb.criteria.ParameterRegistry;
import org.hibernate.ejb.criteria.QueryBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaQueryCompiler;
/**
* Represents a literal expression.
@ -34,16 +37,17 @@ import org.hibernate.ejb.criteria.QueryBuilderImpl;
public class LiteralExpression<T> extends ExpressionImpl<T> {
private final T literal;
public LiteralExpression(QueryBuilderImpl queryBuilder, T literal) {
this( queryBuilder, (Class<T>) determineClass( literal ), literal );
@SuppressWarnings({ "unchecked" })
public LiteralExpression(CriteriaBuilderImpl criteriaBuilder, T literal) {
this( criteriaBuilder, (Class<T>) determineClass( literal ), literal );
}
private static Class determineClass(Object literal) {
return literal == null ? null : literal.getClass();
}
public LiteralExpression(QueryBuilderImpl queryBuilder, Class<T> type, T literal) {
super( queryBuilder, type );
public LiteralExpression(CriteriaBuilderImpl criteriaBuilder, Class<T> type, T literal) {
super( criteriaBuilder, type );
this.literal = literal;
}
@ -54,4 +58,20 @@ public class LiteralExpression<T> extends ExpressionImpl<T> {
public void registerParameters(ParameterRegistry registry) {
// nothign to do
}
public String render(CriteriaQueryCompiler.RenderingContext renderingContext) {
final String parameterName = renderingContext.generateParameterName();
renderingContext.registerImplicitParameterBinding(
new CriteriaQueryCompiler.ImplicitParameterBinding() {
public void bind(TypedQuery typedQuery) {
typedQuery.setParameter( parameterName, getLiteral() );
}
}
);
return ':' + parameterName;
}
public String renderProjection(CriteriaQueryCompiler.RenderingContext renderingContext) {
return render( renderingContext );
}
}

View File

@ -24,9 +24,9 @@
package org.hibernate.ejb.criteria.expression;
import javax.persistence.criteria.Expression;
import org.hibernate.ejb.criteria.ParameterContainer;
import org.hibernate.ejb.criteria.ParameterRegistry;
import org.hibernate.ejb.criteria.QueryBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaQueryCompiler;
/**
* Models an ANSI SQL <tt>NULLIF</tt> expression. <tt>NULLIF</tt> is a specialized <tt>CASE</tt> statement.
@ -38,23 +38,23 @@ public class NullifExpression<T> extends ExpressionImpl<T> {
private final Expression<?> secondaryExpression;
public NullifExpression(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
Class<T> javaType,
Expression<? extends T> primaryExpression,
Expression<?> secondaryExpression) {
super( queryBuilder, (Class<T>)determineType(javaType, primaryExpression) );
super( criteriaBuilder, (Class<T>)determineType(javaType, primaryExpression) );
this.primaryExpression = primaryExpression;
this.secondaryExpression = secondaryExpression;
}
public NullifExpression(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
Class<T> javaType,
Expression<? extends T> primaryExpression,
Object secondaryExpression) {
super( queryBuilder, (Class<T>)determineType(javaType, primaryExpression) );
super( criteriaBuilder, (Class<T>)determineType(javaType, primaryExpression) );
this.primaryExpression = primaryExpression;
this.secondaryExpression = new LiteralExpression( queryBuilder, secondaryExpression );
this.secondaryExpression = new LiteralExpression( criteriaBuilder, secondaryExpression );
}
private static Class determineType(Class javaType, Expression primaryExpression) {
@ -74,4 +74,15 @@ public class NullifExpression<T> extends ExpressionImpl<T> {
Helper.possibleParameter( getSecondaryExpression(), registry );
}
public String render(CriteriaQueryCompiler.RenderingContext renderingContext) {
return "nullif("
+ ( (ExpressionImplementor) getPrimaryExpression() ).render( renderingContext )
+ ','
+ ( (ExpressionImplementor) getSecondaryExpression() ).render( renderingContext )
+ ")";
}
public String renderProjection(CriteriaQueryCompiler.RenderingContext renderingContext) {
return render( renderingContext );
}
}

View File

@ -26,7 +26,8 @@ package org.hibernate.ejb.criteria.expression;
import javax.persistence.criteria.ParameterExpression;
import org.hibernate.ejb.criteria.ParameterRegistry;
import org.hibernate.ejb.criteria.QueryBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaQueryCompiler;
/**
* Defines a parameter specification, or the information about a parameter (where it occurs, what is
@ -39,27 +40,27 @@ public class ParameterExpressionImpl<T> extends ExpressionImpl<T> implements Par
private final Integer position;
public ParameterExpressionImpl(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
Class<T> javaType,
String name) {
super( queryBuilder, javaType );
super( criteriaBuilder, javaType );
this.name = name;
this.position = null;
}
public ParameterExpressionImpl(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
Class<T> javaType,
Integer position) {
super( queryBuilder, javaType );
super( criteriaBuilder, javaType );
this.name = null;
this.position = position;
}
public ParameterExpressionImpl(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
Class<T> javaType) {
super( queryBuilder, javaType );
super( criteriaBuilder, javaType );
this.name = null;
this.position = null;
}
@ -80,4 +81,13 @@ public class ParameterExpressionImpl<T> extends ExpressionImpl<T> implements Par
registry.registerParameter( this );
}
public String render(CriteriaQueryCompiler.RenderingContext renderingContext) {
final String jpaqlParamName = renderingContext.generateParameterName();
renderingContext.registerExplicitParameter( this, jpaqlParamName );
return ':' + jpaqlParamName;
}
public String renderProjection(CriteriaQueryCompiler.RenderingContext renderingContext) {
return render( renderingContext );
}
}

View File

@ -28,10 +28,18 @@ import java.util.List;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.CriteriaBuilder.Case;
import org.hibernate.ejb.criteria.ParameterRegistry;
import org.hibernate.ejb.criteria.QueryBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaQueryCompiler;
/**
* Models what ANSI SQL terms a <tt>searched case expression</tt
* Models what ANSI SQL terms a <tt>searched case expression</tt>. This is a <tt>CASE</tt> expression
* in the form<pre>
* CASE
* WHEN [firstCondition] THEN [firstResult]
* WHEN [secondCondition] THEN [secondResult]
* ELSE [defaultResult]
* END
* </pre>
*
* @author Steve Ebersole
*/
@ -59,9 +67,9 @@ public class SearchedCaseExpression<R> extends ExpressionImpl<R> implements Case
}
public SearchedCaseExpression(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
Class<R> javaType) {
super(queryBuilder, javaType);
super( criteriaBuilder, javaType);
this.javaType = javaType;
}
@ -117,4 +125,21 @@ public class SearchedCaseExpression<R> extends ExpressionImpl<R> implements Case
}
}
public String render(CriteriaQueryCompiler.RenderingContext renderingContext) {
StringBuilder caseStatement = new StringBuilder( "case" );
for ( WhenClause whenClause : getWhenClauses() ) {
caseStatement.append( " when " )
.append( ( (ExpressionImplementor) whenClause.getCondition() ).render( renderingContext ) )
.append( " then " )
.append( ( (ExpressionImplementor) whenClause.getResult() ).render( renderingContext ) );
}
caseStatement.append( " else " )
.append( ( (ExpressionImplementor) getOtherwiseResult() ).render( renderingContext ) )
.append( " end" );
return caseStatement.toString();
}
public String renderProjection(CriteriaQueryCompiler.RenderingContext renderingContext) {
return render( renderingContext );
}
}

View File

@ -27,7 +27,7 @@ import java.util.List;
import javax.persistence.criteria.Selection;
import org.hibernate.ejb.criteria.ParameterContainer;
import org.hibernate.ejb.criteria.QueryBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
/**
* The Hibernate implementation of the JPA {@link Selection}
@ -38,8 +38,8 @@ import org.hibernate.ejb.criteria.QueryBuilderImpl;
public abstract class SelectionImpl<X>
extends AbstractTupleElement<X>
implements Selection<X>, ParameterContainer {
public SelectionImpl(QueryBuilderImpl queryBuilder, Class<X> javaType) {
super( queryBuilder, javaType );
public SelectionImpl(CriteriaBuilderImpl criteriaBuilder, Class<X> javaType) {
super( criteriaBuilder, javaType );
}
public Selection<X> alias(String alias) {

View File

@ -28,10 +28,17 @@ import java.util.List;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.CriteriaBuilder.SimpleCase;
import org.hibernate.ejb.criteria.ParameterRegistry;
import org.hibernate.ejb.criteria.QueryBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaQueryCompiler;
/**
* Models what ANSI SQL terms a simple case statement.
* Models what ANSI SQL terms a simple case statement. This is a <tt>CASE</tt> expression in the form<pre>
* CASE [expression]
* WHEN [firstCondition] THEN [firstResult]
* WHEN [secondCondition] THEN [secondResult]
* ELSE [defaultResult]
* END
* </pre>
*
* @author Steve Ebersole
*/
@ -61,10 +68,10 @@ public class SimpleCaseExpression<C,R> extends ExpressionImpl<R> implements Simp
}
public SimpleCaseExpression(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
Class<R> javaType,
Expression<? extends C> expression) {
super(queryBuilder, javaType);
super( criteriaBuilder, javaType);
this.javaType = javaType;
this.expression = expression;
}
@ -126,4 +133,23 @@ public class SimpleCaseExpression<C,R> extends ExpressionImpl<R> implements Simp
Helper.possibleParameter( getOtherwiseResult(), registry );
}
public String render(CriteriaQueryCompiler.RenderingContext renderingContext) {
StringBuilder caseExpr = new StringBuilder();
caseExpr.append( "case " )
.append( ( (ExpressionImplementor) getExpression() ).render( renderingContext ) )
.append( ' ' );
for ( WhenClause whenClause : getWhenClauses() ) {
caseExpr.append( ( (ExpressionImplementor) whenClause.getCondition() ).render( renderingContext ) )
.append( " then " )
.append( ( (ExpressionImplementor) whenClause.getResult() ).render( renderingContext ) );
}
caseExpr.append( " else " )
.append( ( (ExpressionImplementor) getOtherwiseResult() ).render( renderingContext ) )
.append( " end" );
return caseExpr.toString();
}
public String renderProjection(CriteriaQueryCompiler.RenderingContext renderingContext) {
return render( renderingContext );
}
}

View File

@ -25,7 +25,8 @@ package org.hibernate.ejb.criteria.expression;
import java.util.Collection;
import org.hibernate.ejb.criteria.ParameterRegistry;
import org.hibernate.ejb.criteria.QueryBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaQueryCompiler;
/**
* Represents a "size of" expression in regards to a persistent collection; the implication is
@ -38,9 +39,9 @@ public class SizeOfCollectionExpression<C extends Collection>
private final CollectionExpression<C> collectionExpression;
public SizeOfCollectionExpression(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
CollectionExpression<C> collectionExpression) {
super(queryBuilder, Integer.class);
super( criteriaBuilder, Integer.class);
this.collectionExpression = collectionExpression;
}
@ -52,4 +53,11 @@ public class SizeOfCollectionExpression<C extends Collection>
// nothign to do
}
public String render(CriteriaQueryCompiler.RenderingContext renderingContext) {
return "size of " + getCollectionExpression().render( renderingContext );
}
public String renderProjection(CriteriaQueryCompiler.RenderingContext renderingContext) {
return render( renderingContext );
}
}

View File

@ -25,7 +25,8 @@ package org.hibernate.ejb.criteria.expression;
import javax.persistence.criteria.Subquery;
import org.hibernate.ejb.criteria.ParameterRegistry;
import org.hibernate.ejb.criteria.QueryBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaQueryCompiler;
/**
* Represents a {@link Modifier#ALL}, {@link Modifier#ANY}, {@link Modifier#SOME} modifier appplied to a subquery as
@ -34,17 +35,34 @@ import org.hibernate.ejb.criteria.QueryBuilderImpl;
* @author Steve Ebersole
*/
public class SubqueryComparisonModifierExpression<Y> extends ExpressionImpl<Y> {
public static enum Modifier { ALL, SOME, ANY }
public static enum Modifier {
ALL {
String rendered() {
return "all ";
}
},
SOME {
String rendered() {
return "some ";
}
},
ANY {
String rendered() {
return "any ";
}
};
abstract String rendered();
}
private final Subquery<Y> subquery;
private final Modifier modifier;
public SubqueryComparisonModifierExpression(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
Class<Y> javaType,
Subquery<Y> subquery,
Modifier modifier) {
super(queryBuilder, javaType);
super( criteriaBuilder, javaType);
this.subquery = subquery;
this.modifier = modifier;
}
@ -61,4 +79,11 @@ public class SubqueryComparisonModifierExpression<Y> extends ExpressionImpl<Y> {
// nothign to do (the subquery should be handled directly, and the modified itself is not parameterized)
}
public String render(CriteriaQueryCompiler.RenderingContext renderingContext) {
return getModifier().rendered() + ( ( ExpressionImplementor ) getSubquery() ).render( renderingContext );
}
public String renderProjection(CriteriaQueryCompiler.RenderingContext renderingContext) {
return render( renderingContext );
}
}

View File

@ -25,7 +25,8 @@ package org.hibernate.ejb.criteria.expression;
import javax.persistence.criteria.Expression;
import org.hibernate.ejb.criteria.ParameterRegistry;
import org.hibernate.ejb.criteria.QueryBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaQueryCompiler;
/**
* Models unary arithmetic operation (unary plus and unary minus).
@ -43,11 +44,12 @@ public class UnaryArithmeticOperation<T>
private final Operation operation;
private final Expression<T> operand;
@SuppressWarnings({ "unchecked" })
public UnaryArithmeticOperation(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
Operation operation,
Expression<T> operand) {
super( queryBuilder, (Class)operand.getJavaType() );
super( criteriaBuilder, (Class)operand.getJavaType() );
this.operation = operation;
this.operand = operand;
}
@ -70,4 +72,12 @@ public class UnaryArithmeticOperation<T>
Helper.possibleParameter( getOperand(), registry );
}
public String render(CriteriaQueryCompiler.RenderingContext renderingContext) {
return ( getOperation() == Operation.UNARY_MINUS ? '-' : '+' )
+ ( (ExpressionImplementor) getOperand() ).render( renderingContext );
}
public String renderProjection(CriteriaQueryCompiler.RenderingContext renderingContext) {
return render( renderingContext );
}
}

View File

@ -24,7 +24,7 @@
package org.hibernate.ejb.criteria.expression.function;
import javax.persistence.criteria.Expression;
import org.hibernate.ejb.criteria.QueryBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
/**
* Models the ANSI SQL <tt>ABS</tt> function.
@ -36,7 +36,7 @@ public class AbsFunction<N extends Number>
public static final String NAME = "abs";
public AbsFunction(QueryBuilderImpl queryBuilder, Expression expression) {
super( queryBuilder, expression.getJavaType(), NAME, expression );
public AbsFunction(CriteriaBuilderImpl criteriaBuilder, Expression expression) {
super( criteriaBuilder, expression.getJavaType(), NAME, expression );
}
}

View File

@ -24,7 +24,7 @@
package org.hibernate.ejb.criteria.expression.function;
import javax.persistence.criteria.Expression;
import org.hibernate.ejb.criteria.QueryBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
import org.hibernate.ejb.criteria.expression.LiteralExpression;
/**
@ -36,34 +36,34 @@ public class AggregationFunction<T> extends ParameterizedFunctionExpression<T> {
/**
* Constructs an aggregation function with a single literal argument.
*
* @param queryBuilder The query builder instance.
* @param criteriaBuilder The query builder instance.
* @param returnType The function return type.
* @param functionName The name of the function.
* @param argument The literal argument
*/
@SuppressWarnings({ "unchecked" })
public AggregationFunction(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
Class<T> returnType,
String functionName,
Object argument) {
this( queryBuilder, returnType, functionName, new LiteralExpression( queryBuilder, argument ) );
this( criteriaBuilder, returnType, functionName, new LiteralExpression( criteriaBuilder, argument ) );
}
/**
* Constructs an aggregation function with a single literal argument.
*
* @param queryBuilder The query builder instance.
* @param criteriaBuilder The query builder instance.
* @param returnType The function return type.
* @param functionName The name of the function.
* @param argument The argument
*/
public AggregationFunction(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
Class<T> returnType,
String functionName,
Expression<?> argument) {
super( queryBuilder, returnType, functionName, argument );
super( criteriaBuilder, returnType, functionName, argument );
}
@Override
@ -82,8 +82,8 @@ public class AggregationFunction<T> extends ParameterizedFunctionExpression<T> {
private final boolean distinct;
public COUNT(QueryBuilderImpl queryBuilder, Expression<?> expression, boolean distinct) {
super( queryBuilder, Long.class, NAME , expression );
public COUNT(CriteriaBuilderImpl criteriaBuilder, Expression<?> expression, boolean distinct) {
super( criteriaBuilder, Long.class, NAME , expression );
this.distinct = distinct;
}
@ -101,8 +101,8 @@ public class AggregationFunction<T> extends ParameterizedFunctionExpression<T> {
public static class AVG extends AggregationFunction<Double> {
public static final String NAME = "avg";
public AVG(QueryBuilderImpl queryBuilder, Expression<? extends Number> expression) {
super( queryBuilder, Double.class, NAME, expression );
public AVG(CriteriaBuilderImpl criteriaBuilder, Expression<? extends Number> expression) {
super( criteriaBuilder, Double.class, NAME, expression );
}
}
@ -116,12 +116,12 @@ public class AggregationFunction<T> extends ParameterizedFunctionExpression<T> {
public static final String NAME = "sum";
@SuppressWarnings({ "unchecked" })
public SUM(QueryBuilderImpl queryBuilder, Expression<N> expression) {
super( queryBuilder, (Class<N>)expression.getJavaType(), NAME , expression);
public SUM(CriteriaBuilderImpl criteriaBuilder, Expression<N> expression) {
super( criteriaBuilder, (Class<N>)expression.getJavaType(), NAME , expression);
}
public SUM(QueryBuilderImpl queryBuilder, Expression<? extends Number> expression, Class<N> returnType) {
super( queryBuilder, returnType, NAME , expression);
public SUM(CriteriaBuilderImpl criteriaBuilder, Expression<? extends Number> expression, Class<N> returnType) {
super( criteriaBuilder, returnType, NAME , expression);
}
}
@ -135,8 +135,8 @@ public class AggregationFunction<T> extends ParameterizedFunctionExpression<T> {
public static final String NAME = "min";
@SuppressWarnings({ "unchecked" })
public MIN(QueryBuilderImpl queryBuilder, Expression<N> expression) {
super( queryBuilder, ( Class<N> ) expression.getJavaType(), NAME , expression);
public MIN(CriteriaBuilderImpl criteriaBuilder, Expression<N> expression) {
super( criteriaBuilder, ( Class<N> ) expression.getJavaType(), NAME , expression);
}
}
@ -150,8 +150,8 @@ public class AggregationFunction<T> extends ParameterizedFunctionExpression<T> {
public static final String NAME = "max";
@SuppressWarnings({ "unchecked" })
public MAX(QueryBuilderImpl queryBuilder, Expression<N> expression) {
super( queryBuilder, ( Class<N> ) expression.getJavaType(), NAME , expression);
public MAX(CriteriaBuilderImpl criteriaBuilder, Expression<N> expression) {
super( criteriaBuilder, ( Class<N> ) expression.getJavaType(), NAME , expression);
}
}
@ -164,8 +164,8 @@ public class AggregationFunction<T> extends ParameterizedFunctionExpression<T> {
public static final String NAME = "min";
@SuppressWarnings({ "unchecked" })
public LEAST(QueryBuilderImpl queryBuilder, Expression<X> expression) {
super( queryBuilder, ( Class<X> ) expression.getJavaType(), NAME , expression);
public LEAST(CriteriaBuilderImpl criteriaBuilder, Expression<X> expression) {
super( criteriaBuilder, ( Class<X> ) expression.getJavaType(), NAME , expression);
}
}
@ -178,8 +178,8 @@ public class AggregationFunction<T> extends ParameterizedFunctionExpression<T> {
public static final String NAME = "max";
@SuppressWarnings({ "unchecked" })
public GREATEST(QueryBuilderImpl queryBuilder, Expression<X> expression) {
super( queryBuilder, ( Class<X> ) expression.getJavaType(), NAME , expression);
public GREATEST(CriteriaBuilderImpl criteriaBuilder, Expression<X> expression) {
super( criteriaBuilder, ( Class<X> ) expression.getJavaType(), NAME , expression);
}
}
}

View File

@ -25,7 +25,8 @@ package org.hibernate.ejb.criteria.expression.function;
import org.hibernate.ejb.criteria.ParameterRegistry;
import org.hibernate.ejb.criteria.QueryBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaQueryCompiler;
import org.hibernate.ejb.criteria.expression.ExpressionImpl;
/**
@ -40,10 +41,10 @@ public class BasicFunctionExpression<X>
private final String functionName;
public BasicFunctionExpression(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
Class<X> javaType,
String functionName) {
super( queryBuilder, javaType );
super( criteriaBuilder, javaType );
this.functionName = functionName;
}
@ -62,4 +63,12 @@ public class BasicFunctionExpression<X>
public void registerParameters(ParameterRegistry registry) {
// nothing to do here...
}
public String render(CriteriaQueryCompiler.RenderingContext renderingContext) {
return getFunctionName() + "()";
}
public String renderProjection(CriteriaQueryCompiler.RenderingContext renderingContext) {
return render( renderingContext );
}
}

View File

@ -24,7 +24,7 @@
package org.hibernate.ejb.criteria.expression.function;
import org.hibernate.ejb.criteria.ParameterRegistry;
import org.hibernate.ejb.criteria.QueryBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
import org.hibernate.ejb.criteria.expression.ExpressionImpl;
/**
@ -41,10 +41,10 @@ public class CastFunction<T,Y> extends BasicFunctionExpression<T> implements Fun
private final ExpressionImpl<Y> castSource;
public CastFunction(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
Class<T> javaType,
ExpressionImpl<Y> castSource) {
super( queryBuilder, javaType, CAST_NAME );
super( criteriaBuilder, javaType, CAST_NAME );
this.castSource = castSource;
}

View File

@ -23,7 +23,7 @@
*/
package org.hibernate.ejb.criteria.expression.function;
import org.hibernate.ejb.criteria.QueryBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
/**
* Models the ANSI SQL <tt>CURRENT_DATE</tt> function.
@ -33,7 +33,7 @@ import org.hibernate.ejb.criteria.QueryBuilderImpl;
public class CurrentDateFunction extends BasicFunctionExpression<java.sql.Date> {
public static final String NAME = "current_date";
public CurrentDateFunction(QueryBuilderImpl queryBuilder) {
super( queryBuilder, java.sql.Date.class, NAME );
public CurrentDateFunction(CriteriaBuilderImpl criteriaBuilder) {
super( criteriaBuilder, java.sql.Date.class, NAME );
}
}

View File

@ -23,7 +23,7 @@
*/
package org.hibernate.ejb.criteria.expression.function;
import org.hibernate.ejb.criteria.QueryBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
/**
* Models the ANSI SQL <tt>CURRENT_TIME</tt> function.
@ -33,7 +33,7 @@ import org.hibernate.ejb.criteria.QueryBuilderImpl;
public class CurrentTimeFunction extends BasicFunctionExpression<java.sql.Time> {
public static final String NAME = "current_time";
public CurrentTimeFunction(QueryBuilderImpl queryBuilder) {
super( queryBuilder, java.sql.Time.class, NAME );
public CurrentTimeFunction(CriteriaBuilderImpl criteriaBuilder) {
super( criteriaBuilder, java.sql.Time.class, NAME );
}
}

View File

@ -24,7 +24,7 @@
package org.hibernate.ejb.criteria.expression.function;
import java.sql.Timestamp;
import org.hibernate.ejb.criteria.QueryBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
/**
* Models the ANSI SQL <tt>CURRENT_TIMESTAMP</tt> function.
@ -34,7 +34,7 @@ import org.hibernate.ejb.criteria.QueryBuilderImpl;
public class CurrentTimestampFunction extends BasicFunctionExpression<Timestamp> {
public static final String NAME = "current_timestamp";
public CurrentTimestampFunction(QueryBuilderImpl queryBuilder) {
super( queryBuilder, Timestamp.class, NAME );
public CurrentTimestampFunction(CriteriaBuilderImpl criteriaBuilder) {
super( criteriaBuilder, Timestamp.class, NAME );
}
}

View File

@ -24,7 +24,7 @@
package org.hibernate.ejb.criteria.expression.function;
import javax.persistence.criteria.Expression;
import org.hibernate.ejb.criteria.QueryBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
/**
* Models the ANSI SQL <tt>LENGTH</tt> function.
@ -34,7 +34,7 @@ import org.hibernate.ejb.criteria.QueryBuilderImpl;
public class LengthFunction extends ParameterizedFunctionExpression<Integer> {
public static final String NAME = "length";
public LengthFunction(QueryBuilderImpl queryBuilder, Expression<String> value) {
super( queryBuilder, Integer.class, NAME, value );
public LengthFunction(CriteriaBuilderImpl criteriaBuilder, Expression<String> value) {
super( criteriaBuilder, Integer.class, NAME, value );
}
}

View File

@ -24,9 +24,9 @@
package org.hibernate.ejb.criteria.expression.function;
import javax.persistence.criteria.Expression;
import org.hibernate.ejb.criteria.ParameterContainer;
import org.hibernate.ejb.criteria.ParameterRegistry;
import org.hibernate.ejb.criteria.QueryBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
import org.hibernate.ejb.criteria.expression.LiteralExpression;
/**
@ -42,38 +42,38 @@ public class LocateFunction extends BasicFunctionExpression<Integer> {
private final Expression<Integer> start;
public LocateFunction(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
Expression<String> pattern,
Expression<String> string,
Expression<Integer> start) {
super( queryBuilder, Integer.class, NAME );
super( criteriaBuilder, Integer.class, NAME );
this.pattern = pattern;
this.string = string;
this.start = start;
}
public LocateFunction(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
Expression<String> pattern,
Expression<String> string) {
this( queryBuilder, pattern, string, null );
this( criteriaBuilder, pattern, string, null );
}
public LocateFunction(QueryBuilderImpl queryBuilder, String pattern, Expression<String> string) {
public LocateFunction(CriteriaBuilderImpl criteriaBuilder, String pattern, Expression<String> string) {
this(
queryBuilder,
new LiteralExpression<String>( queryBuilder, pattern ),
criteriaBuilder,
new LiteralExpression<String>( criteriaBuilder, pattern ),
string,
null
);
}
public LocateFunction(QueryBuilderImpl queryBuilder, String pattern, Expression<String> string, int start) {
public LocateFunction(CriteriaBuilderImpl criteriaBuilder, String pattern, Expression<String> string, int start) {
this(
queryBuilder,
new LiteralExpression<String>( queryBuilder, pattern ),
criteriaBuilder,
new LiteralExpression<String>( criteriaBuilder, pattern ),
string,
new LiteralExpression<Integer>( queryBuilder, start )
new LiteralExpression<Integer>( criteriaBuilder, start )
);
}

View File

@ -24,7 +24,7 @@
package org.hibernate.ejb.criteria.expression.function;
import javax.persistence.criteria.Expression;
import org.hibernate.ejb.criteria.QueryBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
/**
* Models the ANSI SQL <tt>LOWER</tt> function.
@ -34,7 +34,7 @@ import org.hibernate.ejb.criteria.QueryBuilderImpl;
public class LowerFunction extends ParameterizedFunctionExpression<String> {
public static final String NAME = "lower";
public LowerFunction(QueryBuilderImpl queryBuilder, Expression<String> string) {
super( queryBuilder, String.class, NAME, string );
public LowerFunction(CriteriaBuilderImpl criteriaBuilder, Expression<String> string) {
super( criteriaBuilder, String.class, NAME, string );
}
}

View File

@ -29,7 +29,7 @@ import java.util.List;
import javax.persistence.criteria.Expression;
import org.hibernate.ejb.criteria.ParameterContainer;
import org.hibernate.ejb.criteria.ParameterRegistry;
import org.hibernate.ejb.criteria.QueryBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
import org.hibernate.ejb.criteria.expression.LiteralExpression;
/**
@ -44,27 +44,27 @@ public class ParameterizedFunctionExpression<X>
private final List<Expression<?>> argumentExpressions;
public ParameterizedFunctionExpression(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
Class<X> javaType,
String functionName,
List<Expression<?>> argumentExpressions) {
super( queryBuilder, javaType, functionName );
super( criteriaBuilder, javaType, functionName );
this.argumentExpressions = argumentExpressions;
}
public ParameterizedFunctionExpression(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
Class<X> javaType,
String functionName,
Expression<?>... argumentExpressions) {
super( queryBuilder, javaType, functionName );
super( criteriaBuilder, javaType, functionName );
this.argumentExpressions = Arrays.asList( argumentExpressions );
}
protected static List<Expression<?>> wrapAsLiterals(QueryBuilderImpl queryBuilder, Object... literalArguments) {
protected static List<Expression<?>> wrapAsLiterals(CriteriaBuilderImpl criteriaBuilder, Object... literalArguments) {
List<Expression<?>> arguments = new ArrayList<Expression<?>>( properSize( literalArguments.length) );
for ( Object o : literalArguments ) {
arguments.add( new LiteralExpression( queryBuilder, o ) );
arguments.add( new LiteralExpression( criteriaBuilder, o ) );
}
return arguments;
}

View File

@ -24,7 +24,7 @@
package org.hibernate.ejb.criteria.expression.function;
import javax.persistence.criteria.Expression;
import org.hibernate.ejb.criteria.QueryBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
/**
* Models the ANSI SQL <tt>SQRT</tt> function.
@ -34,7 +34,7 @@ import org.hibernate.ejb.criteria.QueryBuilderImpl;
public class SqrtFunction extends ParameterizedFunctionExpression<Double> {
public static final String NAME = "sqrt";
public SqrtFunction(QueryBuilderImpl queryBuilder, Expression<? extends Number> expression) {
super( queryBuilder, Double.class, NAME, expression );
public SqrtFunction(CriteriaBuilderImpl criteriaBuilder, Expression<? extends Number> expression) {
super( criteriaBuilder, Double.class, NAME, expression );
}
}

View File

@ -24,9 +24,9 @@
package org.hibernate.ejb.criteria.expression.function;
import javax.persistence.criteria.Expression;
import org.hibernate.ejb.criteria.ParameterContainer;
import org.hibernate.ejb.criteria.ParameterRegistry;
import org.hibernate.ejb.criteria.QueryBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
import org.hibernate.ejb.criteria.expression.LiteralExpression;
/**
@ -42,44 +42,44 @@ public class SubstringFunction extends BasicFunctionExpression<String> {
private final Expression<Integer> length;
public SubstringFunction(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
Expression<String> value,
Expression<Integer> start,
Expression<Integer> length) {
super( queryBuilder, String.class, NAME );
super( criteriaBuilder, String.class, NAME );
this.value = value;
this.start = start;
this.length = length;
}
public SubstringFunction(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
Expression<String> value,
Expression<Integer> start) {
this( queryBuilder, value, start, (Expression<Integer>)null );
this( criteriaBuilder, value, start, (Expression<Integer>)null );
}
public SubstringFunction(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
Expression<String> value,
int start) {
this(
queryBuilder,
this(
criteriaBuilder,
value,
new LiteralExpression<Integer>( queryBuilder, start )
new LiteralExpression<Integer>( criteriaBuilder, start )
);
}
public SubstringFunction(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
Expression<String> value,
int start,
int length) {
this(
queryBuilder,
criteriaBuilder,
value,
new LiteralExpression<Integer>( queryBuilder, start ),
new LiteralExpression<Integer>( queryBuilder, length )
new LiteralExpression<Integer>( criteriaBuilder, start ),
new LiteralExpression<Integer>( criteriaBuilder, length )
);
}

View File

@ -26,7 +26,7 @@ package org.hibernate.ejb.criteria.expression.function;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.CriteriaBuilder.Trimspec;
import org.hibernate.ejb.criteria.ParameterRegistry;
import org.hibernate.ejb.criteria.QueryBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
import org.hibernate.ejb.criteria.expression.LiteralExpression;
/**
@ -44,52 +44,52 @@ public class TrimFunction extends BasicFunctionExpression<String> {
private final Expression<String> trimSource;
public TrimFunction(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
Trimspec trimspec,
Expression<Character> trimCharacter,
Expression<String> trimSource) {
super( queryBuilder, String.class, NAME );
super( criteriaBuilder, String.class, NAME );
this.trimspec = trimspec;
this.trimCharacter = trimCharacter;
this.trimSource = trimSource;
}
public TrimFunction(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
Trimspec trimspec,
char trimCharacter,
Expression<String> trimSource) {
super( queryBuilder, String.class, NAME );
super( criteriaBuilder, String.class, NAME );
this.trimspec = trimspec;
this.trimCharacter = new LiteralExpression<Character>( queryBuilder, trimCharacter );
this.trimCharacter = new LiteralExpression<Character>( criteriaBuilder, trimCharacter );
this.trimSource = trimSource;
}
public TrimFunction(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
Expression<String> trimSource) {
this( queryBuilder, DEFAULT_TRIMSPEC, DEFAULT_TRIM_CHAR, trimSource );
this( criteriaBuilder, DEFAULT_TRIMSPEC, DEFAULT_TRIM_CHAR, trimSource );
}
public TrimFunction(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
Expression<Character> trimCharacter,
Expression<String> trimSource) {
this( queryBuilder, DEFAULT_TRIMSPEC, trimCharacter, trimSource );
this( criteriaBuilder, DEFAULT_TRIMSPEC, trimCharacter, trimSource );
}
public TrimFunction(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
char trimCharacter,
Expression<String> trimSource) {
this( queryBuilder, DEFAULT_TRIMSPEC, trimCharacter, trimSource );
this( criteriaBuilder, DEFAULT_TRIMSPEC, trimCharacter, trimSource );
}
public TrimFunction(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
Trimspec trimspec,
Expression<String> trimSource) {
this( queryBuilder, trimspec, DEFAULT_TRIM_CHAR, trimSource );
this( criteriaBuilder, trimspec, DEFAULT_TRIM_CHAR, trimSource );
}
public Expression<Character> getTrimCharacter() {

View File

@ -24,7 +24,7 @@
package org.hibernate.ejb.criteria.expression.function;
import javax.persistence.criteria.Expression;
import org.hibernate.ejb.criteria.QueryBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
/**
* Models the ANSI SQL <tt>UPPER</tt> function.
@ -34,7 +34,7 @@ import org.hibernate.ejb.criteria.QueryBuilderImpl;
public class UpperFunction extends ParameterizedFunctionExpression<String> {
public static final String NAME = "upper";
public UpperFunction(QueryBuilderImpl queryBuilder, Expression<String> string) {
super( queryBuilder, String.class, NAME, string );
public UpperFunction(CriteriaBuilderImpl criteriaBuilder, Expression<String> string) {
super( criteriaBuilder, String.class, NAME, string );
}
}

View File

@ -28,7 +28,7 @@ import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Selection;
import org.hibernate.ejb.criteria.expression.ExpressionImpl;
import org.hibernate.ejb.criteria.QueryBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
/**
* Basic template support for {@link Predicate} implementors providing
@ -39,8 +39,8 @@ import org.hibernate.ejb.criteria.QueryBuilderImpl;
public abstract class AbstractPredicateImpl extends ExpressionImpl<Boolean> implements Predicate {
private boolean negated;
protected AbstractPredicateImpl(QueryBuilderImpl queryBuilder) {
super( queryBuilder, Boolean.class );
protected AbstractPredicateImpl(CriteriaBuilderImpl criteriaBuilder) {
super( criteriaBuilder, Boolean.class );
}
public boolean isNegated() {

View File

@ -27,7 +27,7 @@ import java.util.List;
import java.util.Collections;
import javax.persistence.criteria.Expression;
import org.hibernate.ejb.criteria.QueryBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
/**
* TODO : javadoc
@ -37,8 +37,8 @@ import org.hibernate.ejb.criteria.QueryBuilderImpl;
public abstract class AbstractSimplePredicate extends AbstractPredicateImpl {
private static final List<Expression<Boolean>> NO_EXPRESSIONS = Collections.emptyList();
public AbstractSimplePredicate(QueryBuilderImpl queryBuilder) {
super( queryBuilder );
public AbstractSimplePredicate(CriteriaBuilderImpl criteriaBuilder) {
super( criteriaBuilder );
}
public BooleanOperator getOperator() {

View File

@ -25,9 +25,10 @@ package org.hibernate.ejb.criteria.predicate;
import javax.persistence.criteria.Expression;
import org.hibernate.ejb.criteria.ParameterContainer;
import org.hibernate.ejb.criteria.ParameterRegistry;
import org.hibernate.ejb.criteria.QueryBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaQueryCompiler;
import org.hibernate.ejb.criteria.expression.ExpressionImplementor;
/**
* Models a <tt>BETWEEN</tt> {@link javax.persistence.criteria.Predicate}.
@ -40,24 +41,24 @@ public class BetweenPredicate<Y> extends AbstractSimplePredicate {
private final Expression<? extends Y> upperBound;
public BetweenPredicate(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
Expression<? extends Y> expression,
Y lowerBound,
Y upperBound) {
this(
queryBuilder,
criteriaBuilder,
expression,
queryBuilder.literal( lowerBound ),
queryBuilder.literal( upperBound )
criteriaBuilder.literal( lowerBound ),
criteriaBuilder.literal( upperBound )
);
}
public BetweenPredicate(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
Expression<? extends Y> expression,
Expression<? extends Y> lowerBound,
Expression<? extends Y> upperBound) {
super( queryBuilder );
super( criteriaBuilder );
this.expression = expression;
this.lowerBound = lowerBound;
this.upperBound = upperBound;
@ -81,4 +82,15 @@ public class BetweenPredicate<Y> extends AbstractSimplePredicate {
Helper.possibleParameter( getUpperBound(), registry );
}
public String render(CriteriaQueryCompiler.RenderingContext renderingContext) {
return ( (ExpressionImplementor) getExpression() ).render( renderingContext )
+ " between "
+ ( (ExpressionImplementor) getLowerBound() ).render( renderingContext )
+ " and "
+ ( (ExpressionImplementor) getUpperBound() ).render( renderingContext );
}
public String renderProjection(CriteriaQueryCompiler.RenderingContext renderingContext) {
return render( renderingContext );
}
}

View File

@ -27,7 +27,9 @@ import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Predicate;
import org.hibernate.ejb.criteria.ParameterRegistry;
import org.hibernate.ejb.criteria.QueryBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaQueryCompiler;
import org.hibernate.ejb.criteria.expression.ExpressionImplementor;
/**
* Defines a {@link Predicate} used to wrap an {@link Expression Expression&lt;Boolean&gt;}.
@ -37,8 +39,8 @@ import org.hibernate.ejb.criteria.QueryBuilderImpl;
public class BooleanExpressionPredicate extends AbstractSimplePredicate {
private final Expression<Boolean> expression;
public BooleanExpressionPredicate(QueryBuilderImpl queryBuilder, Expression<Boolean> expression) {
super( queryBuilder );
public BooleanExpressionPredicate(CriteriaBuilderImpl criteriaBuilder, Expression<Boolean> expression) {
super( criteriaBuilder );
this.expression = expression;
}
@ -54,4 +56,12 @@ public class BooleanExpressionPredicate extends AbstractSimplePredicate {
public void registerParameters(ParameterRegistry registry) {
Helper.possibleParameter(expression, registry);
}
public String render(CriteriaQueryCompiler.RenderingContext renderingContext) {
return ( ( ExpressionImplementor) getExpression() ).render( renderingContext );
}
public String renderProjection(CriteriaQueryCompiler.RenderingContext renderingContext) {
return render( renderingContext );
}
}

View File

@ -26,9 +26,11 @@ package org.hibernate.ejb.criteria.predicate;
import javax.persistence.criteria.Expression;
import org.hibernate.ejb.criteria.ParameterRegistry;
import org.hibernate.ejb.criteria.QueryBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaQueryCompiler;
import org.hibernate.ejb.criteria.expression.BinaryOperatorExpression;
import org.hibernate.ejb.criteria.expression.LiteralExpression;
import org.hibernate.ejb.criteria.expression.ExpressionImplementor;
/**
* Models a basic relational comparison predicate.
@ -41,25 +43,26 @@ public class ComparisonPredicate extends AbstractSimplePredicate implements Bina
private final Expression<?> rightHandSide;
public ComparisonPredicate(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
ComparisonOperator comparisonOperator,
Expression<?> leftHandSide,
Expression<?> rightHandSide) {
super( queryBuilder );
super( criteriaBuilder );
this.comparisonOperator = comparisonOperator;
this.leftHandSide = leftHandSide;
this.rightHandSide = rightHandSide;
}
@SuppressWarnings({ "unchecked" })
public ComparisonPredicate(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
ComparisonOperator comparisonOperator,
Expression<?> leftHandSide,
Object rightHandSide) {
super( queryBuilder );
super( criteriaBuilder );
this.comparisonOperator = comparisonOperator;
this.leftHandSide = leftHandSide;
this.rightHandSide = new LiteralExpression( queryBuilder, rightHandSide );
this.rightHandSide = new LiteralExpression( criteriaBuilder, rightHandSide );
}
public ComparisonOperator getComparisonOperator() {
@ -88,33 +91,63 @@ public class ComparisonPredicate extends AbstractSimplePredicate implements Bina
public ComparisonOperator negated() {
return NOT_EQUAL;
}
public String rendered() {
return "=";
}
},
NOT_EQUAL {
public ComparisonOperator negated() {
return EQUAL;
}
public String rendered() {
return "<>";
}
},
LESS_THAN {
public ComparisonOperator negated() {
return GREATER_THAN_OR_EQUAL;
}
public String rendered() {
return "<";
}
},
LESS_THAN_OR_EQUAL {
public ComparisonOperator negated() {
return GREATER_THAN;
}
public String rendered() {
return "<=";
}
},
GREATER_THAN {
public ComparisonOperator negated() {
return LESS_THAN_OR_EQUAL;
}
public String rendered() {
return ">";
}
},
GREATER_THAN_OR_EQUAL {
public ComparisonOperator negated() {
return LESS_THAN;
}
public String rendered() {
return ">=";
}
};
public abstract ComparisonOperator negated();
public abstract String rendered();
}
public String render(CriteriaQueryCompiler.RenderingContext renderingContext) {
return ( ( ExpressionImplementor) getLeftHandOperand() ).render( renderingContext )
+ getComparisonOperator().rendered()
+ ( ( ExpressionImplementor) getRightHandOperand() ).render( renderingContext );
}
public String renderProjection(CriteriaQueryCompiler.RenderingContext renderingContext) {
return render( renderingContext );
}
}

View File

@ -29,9 +29,10 @@ import java.util.Arrays;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Expression;
import org.hibernate.ejb.criteria.ParameterContainer;
import org.hibernate.ejb.criteria.ParameterRegistry;
import org.hibernate.ejb.criteria.QueryBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaQueryCompiler;
import org.hibernate.ejb.criteria.expression.ExpressionImplementor;
/**
* A compound {@link Predicate predicate} is a grouping of other {@link Predicate predicates} in order to apply
@ -46,44 +47,44 @@ public class CompoundPredicate extends AbstractPredicateImpl {
/**
* Constructs an empty conjunction or disjunction.
*
* @param queryBuilder The query builder from whcih this originates.
* @param criteriaBuilder The query builder from whcih this originates.
* @param operator Indicates whether this predicate will funtion
* as a conjunction or disjuntion.
*/
public CompoundPredicate(QueryBuilderImpl queryBuilder, BooleanOperator operator) {
super( queryBuilder );
public CompoundPredicate(CriteriaBuilderImpl criteriaBuilder, BooleanOperator operator) {
super( criteriaBuilder );
this.operator = operator;
}
/**
* Constructs a conjunction or disjunction over the given expressions.
*
* @param queryBuilder The query builder from which this originates.
* @param criteriaBuilder The query builder from which this originates.
* @param operator Indicates whether this predicate will funtion
* as a conjunction or disjuntion.
* @param expressions The expressions to be grouped.
*/
public CompoundPredicate(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
BooleanOperator operator,
Expression<Boolean>... expressions) {
this( queryBuilder, operator );
this( criteriaBuilder, operator );
applyExpressions( expressions );
}
/**
* Constructs a conjunction or disjunction over the given expressions.
*
* @param queryBuilder The query builder from whcih this originates.
* @param criteriaBuilder The query builder from whcih this originates.
* @param operator Indicates whether this predicate will funtion
* as a conjunction or disjuntion.
* @param expressions The expressions to be grouped.
*/
public CompoundPredicate(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
BooleanOperator operator,
List<Expression<Boolean>> expressions) {
this( queryBuilder, operator );
this( criteriaBuilder, operator );
applyExpressions( expressions );
}
@ -110,4 +111,29 @@ public class CompoundPredicate extends AbstractPredicateImpl {
}
}
public String render(CriteriaQueryCompiler.RenderingContext renderingContext) {
if ( getExpressions().size() == 1 ) {
return ( (ExpressionImplementor) getExpressions().get(0) ).render( renderingContext );
}
final StringBuilder buffer = new StringBuilder();
String sep = "";
for ( Expression expression : getExpressions() ) {
buffer.append( sep )
.append( "( " )
.append( ( (ExpressionImplementor) expression ).render( renderingContext ) )
.append( " )" );
sep = operatorTextWithSeparator();
}
return buffer.toString();
}
private String operatorTextWithSeparator() {
return getOperator() == BooleanOperator.AND
? " and "
: " or ";
}
public String renderProjection(CriteriaQueryCompiler.RenderingContext renderingContext) {
return render( renderingContext );
}
}

View File

@ -25,7 +25,9 @@ package org.hibernate.ejb.criteria.predicate;
import javax.persistence.criteria.Subquery;
import org.hibernate.ejb.criteria.ParameterRegistry;
import org.hibernate.ejb.criteria.QueryBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaQueryCompiler;
import org.hibernate.ejb.criteria.expression.ExpressionImplementor;
/**
* Models an <tt>EXISTS(<subquery>)</tt> predicate
@ -35,8 +37,8 @@ import org.hibernate.ejb.criteria.QueryBuilderImpl;
public class ExistsPredicate extends AbstractSimplePredicate {
private final Subquery<?> subquery;
public ExistsPredicate(QueryBuilderImpl queryBuilder, Subquery<?> subquery) {
super(queryBuilder);
public ExistsPredicate(CriteriaBuilderImpl criteriaBuilder, Subquery<?> subquery) {
super( criteriaBuilder );
this.subquery = subquery;
}
@ -48,4 +50,12 @@ public class ExistsPredicate extends AbstractSimplePredicate {
// nothing to do here
}
public String render(CriteriaQueryCompiler.RenderingContext renderingContext) {
return ( isNegated() ? "not " : "" ) + "exists "
+ ( ( ExpressionImplementor ) getSubquery() ).render( renderingContext );
}
public String renderProjection(CriteriaQueryCompiler.RenderingContext renderingContext) {
return render( renderingContext );
}
}

View File

@ -26,7 +26,9 @@ package org.hibernate.ejb.criteria.predicate;
import javax.persistence.criteria.Expression;
import org.hibernate.ejb.criteria.ParameterRegistry;
import org.hibernate.ejb.criteria.QueryBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaQueryCompiler;
import org.hibernate.ejb.criteria.expression.ExpressionImplementor;
/**
* ANSI-SQL defines <tt>TRUE</tt>, <tt>FALSE</tt> and <tt>UNKNOWN</tt> as <i>truth values</i>. These
@ -43,8 +45,8 @@ public class ExplicitTruthValueCheck extends AbstractSimplePredicate {
private final Expression<Boolean> booleanExpression;
private final TruthValue truthValue;
public ExplicitTruthValueCheck(QueryBuilderImpl queryBuilder, Expression<Boolean> booleanExpression, TruthValue truthValue) {
super( queryBuilder );
public ExplicitTruthValueCheck(CriteriaBuilderImpl criteriaBuilder, Expression<Boolean> booleanExpression, TruthValue truthValue) {
super( criteriaBuilder );
this.booleanExpression = booleanExpression;
this.truthValue = truthValue;
}
@ -60,5 +62,15 @@ public class ExplicitTruthValueCheck extends AbstractSimplePredicate {
public void registerParameters(ParameterRegistry registry) {
Helper.possibleParameter( getBooleanExpression(), registry );
}
public String render(CriteriaQueryCompiler.RenderingContext renderingContext) {
return ( (ExpressionImplementor) getBooleanExpression() ).render( renderingContext )
+ " = "
+ ( getTruthValue() == TruthValue.TRUE ? "true" : "false" );
}
public String renderProjection(CriteriaQueryCompiler.RenderingContext renderingContext) {
return render( renderingContext );
}
}

View File

@ -28,58 +28,61 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Subquery;
import org.hibernate.ejb.criteria.ParameterRegistry;
import org.hibernate.ejb.criteria.QueryBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaQueryCompiler;
import org.hibernate.ejb.criteria.expression.LiteralExpression;
import org.hibernate.ejb.criteria.expression.ExpressionImplementor;
/**
* TODO : javadoc
*
* @author Steve Ebersole
*/
public class InPredicate<T> extends AbstractSimplePredicate implements QueryBuilderImpl.In<T> {
public class InPredicate<T> extends AbstractSimplePredicate implements CriteriaBuilderImpl.In<T> {
private final Expression<? extends T> expression;
private final List<Expression<? extends T>> values;
/**
* Constructs an <tt>IN</tt> predicate against a given expression with an empty list of values.
*
* @param queryBuilder The query builder from which this originates.
* @param criteriaBuilder The query builder from which this originates.
* @param expression The expression.
*/
public InPredicate(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
Expression<? extends T> expression) {
this( queryBuilder, expression, new ArrayList<Expression<? extends T>>() );
this( criteriaBuilder, expression, new ArrayList<Expression<? extends T>>() );
}
/**
* Constructs an <tt>IN</tt> predicate against a given expression with the given list of expression values.
*
* @param queryBuilder The query builder from which this originates.
* @param criteriaBuilder The query builder from which this originates.
* @param expression The expression.
* @param values The value list.
*/
public InPredicate(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
Expression<? extends T> expression,
Expression<? extends T>... values) {
this( queryBuilder, expression, Arrays.asList( values ) );
this( criteriaBuilder, expression, Arrays.asList( values ) );
}
/**
* Constructs an <tt>IN</tt> predicate against a given expression with the given list of expression values.
*
* @param queryBuilder The query builder from which this originates.
* @param criteriaBuilder The query builder from which this originates.
* @param expression The expression.
* @param values The value list.
*/
public InPredicate(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
Expression<? extends T> expression,
List<Expression<? extends T>> values) {
super( queryBuilder );
super( criteriaBuilder );
this.expression = expression;
this.values = values;
}
@ -87,34 +90,34 @@ public class InPredicate<T> extends AbstractSimplePredicate implements QueryBuil
/**
* Constructs an <tt>IN</tt> predicate against a given expression with the given given literal value list.
*
* @param queryBuilder The query builder from which this originates.
* @param criteriaBuilder The query builder from which this originates.
* @param expression The expression.
* @param values The value list.
*/
public InPredicate(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
Expression<? extends T> expression,
T... values) {
this( queryBuilder, expression, Arrays.asList( values ) );
this( criteriaBuilder, expression, Arrays.asList( values ) );
}
/**
* Constructs an <tt>IN</tt> predicate against a given expression with the given literal value list.
*
* @param queryBuilder The query builder from which this originates.
* @param criteriaBuilder The query builder from which this originates.
* @param expression The expression.
* @param values The value list.
*/
public InPredicate(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
Expression<? extends T> expression,
Collection<T> values) {
super( queryBuilder );
super( criteriaBuilder );
this.expression = expression;
// TODO : size this?
this.values = new ArrayList<Expression<? extends T>>();
for ( T value : values ) {
this.values.add( new LiteralExpression<T>( queryBuilder, value ) );
this.values.add( new LiteralExpression<T>( criteriaBuilder, value ) );
}
}
@ -146,4 +149,31 @@ public class InPredicate<T> extends AbstractSimplePredicate implements QueryBuil
Helper.possibleParameter(value, registry);
}
}
public String render(CriteriaQueryCompiler.RenderingContext renderingContext) {
StringBuilder buffer = new StringBuilder( "in" );
// subquery expressions are already wrapped in parenthesis, so we only
// need to render the parens here if the values represent an explicit value list
boolean isInSubqueryPredicate = getValues().size() == 1
&& Subquery.class.isInstance( getValues().get( 0 ) );
if ( isInSubqueryPredicate ) {
buffer.append( ( (ExpressionImplementor) getValues().get(0) ).render( renderingContext ) );
}
else {
buffer.append( '(' );
String sep = "";
for ( Expression value : getValues() ) {
buffer.append( sep )
.append( ( (ExpressionImplementor) value ).render( renderingContext ) );
sep = ", ";
}
buffer.append( ')' );
}
return buffer.toString();
}
public String renderProjection(CriteriaQueryCompiler.RenderingContext renderingContext) {
return render( renderingContext );
}
}

View File

@ -25,7 +25,8 @@ package org.hibernate.ejb.criteria.predicate;
import java.util.Collection;
import org.hibernate.ejb.criteria.ParameterRegistry;
import org.hibernate.ejb.criteria.QueryBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaQueryCompiler;
import org.hibernate.ejb.criteria.expression.CollectionExpression;
import org.hibernate.ejb.criteria.expression.UnaryOperatorExpression;
@ -41,9 +42,9 @@ public class IsEmptyPredicate<C extends Collection>
private final CollectionExpression<C> collectionExpression;
public IsEmptyPredicate(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
CollectionExpression<C> collectionExpression) {
super(queryBuilder);
super( criteriaBuilder );
this.collectionExpression = collectionExpression;
}
@ -55,4 +56,11 @@ public class IsEmptyPredicate<C extends Collection>
// nothing to do
}
public String render(CriteriaQueryCompiler.RenderingContext renderingContext) {
return getOperand().render( renderingContext ) + " is empty";
}
public String renderProjection(CriteriaQueryCompiler.RenderingContext renderingContext) {
return render( renderingContext );
}
}

View File

@ -25,11 +25,13 @@ package org.hibernate.ejb.criteria.predicate;
import javax.persistence.criteria.Expression;
import org.hibernate.ejb.criteria.ParameterRegistry;
import org.hibernate.ejb.criteria.QueryBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaQueryCompiler;
import org.hibernate.ejb.criteria.expression.LiteralExpression;
import org.hibernate.ejb.criteria.expression.ExpressionImplementor;
/**
* TODO : javadoc
* Models a SQL <tt>LIKE</tt> expression.
*
* @author Steve Ebersole
*/
@ -39,65 +41,65 @@ public class LikePredicate extends AbstractSimplePredicate {
private final Expression<Character> escapeCharacter;
public LikePredicate(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
Expression<String> matchExpression,
Expression<String> pattern) {
this( queryBuilder, matchExpression, pattern, null );
this( criteriaBuilder, matchExpression, pattern, null );
}
public LikePredicate(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
Expression<String> matchExpression,
String pattern) {
this( queryBuilder, matchExpression, new LiteralExpression<String>( queryBuilder, pattern) );
this( criteriaBuilder, matchExpression, new LiteralExpression<String>( criteriaBuilder, pattern) );
}
public LikePredicate(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
Expression<String> matchExpression,
Expression<String> pattern,
Expression<Character> escapeCharacter) {
super( queryBuilder );
super( criteriaBuilder );
this.matchExpression = matchExpression;
this.pattern = pattern;
this.escapeCharacter = escapeCharacter;
}
public LikePredicate(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
Expression<String> matchExpression,
Expression<String> pattern,
char escapeCharacter) {
this(
queryBuilder,
criteriaBuilder,
matchExpression,
pattern,
new LiteralExpression<Character>( queryBuilder, escapeCharacter )
new LiteralExpression<Character>( criteriaBuilder, escapeCharacter )
);
}
public LikePredicate(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
Expression<String> matchExpression,
String pattern,
char escapeCharacter) {
this(
queryBuilder,
criteriaBuilder,
matchExpression,
new LiteralExpression<String>( queryBuilder, pattern ),
new LiteralExpression<Character>( queryBuilder, escapeCharacter )
new LiteralExpression<String>( criteriaBuilder, pattern ),
new LiteralExpression<Character>( criteriaBuilder, escapeCharacter )
);
}
public LikePredicate(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
Expression<String> matchExpression,
String pattern,
Expression<Character> escapeCharacter) {
this(
queryBuilder,
criteriaBuilder,
matchExpression,
new LiteralExpression<String>( queryBuilder, pattern ),
new LiteralExpression<String>( criteriaBuilder, pattern ),
escapeCharacter
);
}
@ -120,5 +122,19 @@ public class LikePredicate extends AbstractSimplePredicate {
Helper.possibleParameter( getPattern(), registry );
}
public String render(CriteriaQueryCompiler.RenderingContext renderingContext) {
StringBuilder likeExpr = new StringBuilder();
likeExpr.append( ( (ExpressionImplementor) getMatchExpression() ).render( renderingContext ) )
.append( " like " )
.append( ( (ExpressionImplementor) getPattern() ).render( renderingContext ) );
if ( escapeCharacter != null ) {
likeExpr.append( " escape " )
.append( ( (ExpressionImplementor) getEscapeCharacter() ).render( renderingContext ) );
}
return likeExpr.toString();
}
public String renderProjection(CriteriaQueryCompiler.RenderingContext renderingContext) {
return render( renderingContext );
}
}

View File

@ -26,7 +26,8 @@ package org.hibernate.ejb.criteria.predicate;
import java.util.Collection;
import javax.persistence.criteria.Expression;
import org.hibernate.ejb.criteria.ParameterRegistry;
import org.hibernate.ejb.criteria.QueryBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaQueryCompiler;
import org.hibernate.ejb.criteria.expression.CollectionExpression;
import org.hibernate.ejb.criteria.expression.LiteralExpression;
@ -42,21 +43,21 @@ public class MemberOfPredicate<E, C extends Collection<E>>
private final CollectionExpression<C> collectionExpression;
public MemberOfPredicate(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
Expression<E> elementExpression,
CollectionExpression<C> collectionExpression) {
super(queryBuilder);
super( criteriaBuilder );
this.elementExpression = elementExpression;
this.collectionExpression = collectionExpression;
}
public MemberOfPredicate(
QueryBuilderImpl queryBuilder,
CriteriaBuilderImpl criteriaBuilder,
E element,
CollectionExpression<C> collectionExpression) {
this(
queryBuilder,
new LiteralExpression<E>( queryBuilder, element ),
criteriaBuilder,
new LiteralExpression<E>( criteriaBuilder, element ),
collectionExpression
);
}
@ -74,4 +75,12 @@ public class MemberOfPredicate<E, C extends Collection<E>>
Helper.possibleParameter( getElementExpression(), registry );
}
public String render(CriteriaQueryCompiler.RenderingContext renderingContext) {
return ( isNegated() ? "not " : "" ) + "member of "
+ collectionExpression.render( renderingContext );
}
public String renderProjection(CriteriaQueryCompiler.RenderingContext renderingContext) {
return render( renderingContext );
}
}

View File

@ -26,15 +26,17 @@ package org.hibernate.ejb.criteria.predicate;
import javax.persistence.criteria.Expression;
import org.hibernate.ejb.criteria.ParameterRegistry;
import org.hibernate.ejb.criteria.QueryBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaQueryCompiler;
import org.hibernate.ejb.criteria.expression.UnaryOperatorExpression;
import org.hibernate.ejb.criteria.expression.ExpressionImplementor;
/**
* Defines a {@link javax.persistence.criteria.Predicate} for checking the
* nullness state of an expression, aka an <tt>IS (NOT?) NULL</tt> predicate.
* <p/>
* The <tt>NOT NULL</tt> form can be built by calling the constructor and then
* calling {@link #negate}.
* calling {@link #not}.
*
* @author Steve Ebersole
*/
@ -43,14 +45,14 @@ public class NullnessPredicate extends AbstractSimplePredicate implements UnaryO
/**
* Constructs the affirmitive form of nullness checking (<i>IS NULL</i>). To
* construct the negative form (<i>IS NOT NULL</i>) call {@link #negate} on the
* construct the negative form (<i>IS NOT NULL</i>) call {@link #not} on the
* constructed instance.
*
* @param queryBuilder The query builder from whcih this originates.
* @param expression The expression to check.
* @param criteriaBuilder The query builder from whcih this originates.
* @param operand The expression to check.
*/
public NullnessPredicate(QueryBuilderImpl queryBuilder, Expression<?> operand) {
super( queryBuilder );
public NullnessPredicate(CriteriaBuilderImpl criteriaBuilder, Expression<?> operand) {
super( criteriaBuilder );
this.operand = operand;
}
@ -61,4 +63,18 @@ public class NullnessPredicate extends AbstractSimplePredicate implements UnaryO
public void registerParameters(ParameterRegistry registry) {
Helper.possibleParameter( getOperand(), registry );
}
public String render(CriteriaQueryCompiler.RenderingContext renderingContext) {
return ( (ExpressionImplementor) operand ).render( renderingContext ) + check();
}
private String check() {
return isNegated()
? " is not null"
: " is null";
}
public String renderProjection(CriteriaQueryCompiler.RenderingContext renderingContext) {
return render( renderingContext );
}
}

View File

@ -41,19 +41,10 @@ public class BasicCriteriaUsageTest extends TestCase {
return new Class[] { Wall.class };
}
public void testSimplestCriterias() {
EntityManager em = getOrCreateEntityManager();
em.getTransaction().begin();
CriteriaQuery criteria = em.getCriteriaBuilder().createQuery();
criteria.from( Wall.class );
em.getTransaction().commit();
em.close();
}
public void testParameterCollection() {
EntityManager em = getOrCreateEntityManager();
em.getTransaction().begin();
CriteriaQuery criteria = em.getCriteriaBuilder().createQuery();
CriteriaQuery<Wall> criteria = em.getCriteriaBuilder().createQuery( Wall.class );
Root<Wall> from = criteria.from( Wall.class );
ParameterExpression param = em.getCriteriaBuilder().parameter( String.class );
SingularAttribute<? super Wall,?> colorAttribute = em.getMetamodel()
@ -66,4 +57,14 @@ public class BasicCriteriaUsageTest extends TestCase {
em.getTransaction().commit();
em.close();
}
public void testTrivialCompilation() {
EntityManager em = getOrCreateEntityManager();
em.getTransaction().begin();
CriteriaQuery<Wall> criteria = em.getCriteriaBuilder().createQuery( Wall.class );
criteria.from( Wall.class );
em.createQuery( criteria ).getResultList();
em.getTransaction().commit();
em.close();
}
}