HHH-4756 - javax.persistence.criteria.Path#get should result in *delayed* join rendering

git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@18436 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
Steve Ebersole 2010-01-07 17:58:37 +00:00
parent afbf1be5b3
commit 84ed210c39
46 changed files with 2018 additions and 1993 deletions

View File

@ -1,184 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
* third-party contributors as indicated by either @author tags or express
* copyright attribution statements applied by the authors. All
* third-party contributions are distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.ejb.criteria;
import java.io.Serializable;
import javax.persistence.criteria.CollectionJoin;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Fetch;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.ListJoin;
import javax.persistence.criteria.MapJoin;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.PluralJoin;
import javax.persistence.criteria.SetJoin;
import javax.persistence.metamodel.CollectionAttribute;
import javax.persistence.metamodel.ListAttribute;
import javax.persistence.metamodel.MapAttribute;
import javax.persistence.metamodel.PluralAttribute;
import javax.persistence.metamodel.SingularAttribute;
/**
* Convenience base class for all basic collection joins. Mainly we handle the fact that
* this path cannot be further de-referenced.
*
* @author Steve Ebersole
*/
public abstract class AbstractBasicPluralJoin<O,C,E>
extends JoinImpl<O,E>
implements PluralJoin<O,C,E>, Fetch<O,E>, Serializable {
public AbstractBasicPluralJoin(
CriteriaBuilderImpl criteriaBuilder,
Class<E> javaType,
PathImpl<O> lhs,
PluralAttribute<? super O, ?, ?> joinProperty,
JoinType joinType) {
super( criteriaBuilder, javaType, lhs, joinProperty, joinType);
}
@Override
public PluralAttribute<? super O, C, E> getModel() {
return ( PluralAttribute<? super O, C, E> ) super.getAttribute();
}
@Override
public Expression<Class<? extends E>> type(){
throw new BasicPathUsageException( "type() is not applicable to primitive paths.", getAttribute() );
}
@Override
public <Y> Path<Y> get(SingularAttribute<? super E, Y> attribute){
throw illegalDereference();
}
private BasicPathUsageException illegalDereference() {
return new BasicPathUsageException( "Basic collection elements cannot be de-referenced", getAttribute() );
}
@Override
public <Y, C extends java.util.Collection<Y>> Expression<C> get(PluralAttribute<E, C, Y> collection){
throw illegalDereference();
}
@Override
public <L, W, M extends java.util.Map<L, W>> Expression<M> get(MapAttribute<E, L, W> map){
throw illegalDereference();
}
@Override
public <Y> Path<Y> get(String attName) {
throw illegalDereference();
}
@Override
public <Y> Join<E, Y> join(SingularAttribute<? super E, Y> attribute, JoinType jt) {
throw illegalJoin();
}
private BasicPathUsageException illegalJoin() {
return new BasicPathUsageException( "Basic collection cannot be source of a join", getAttribute() );
}
@Override
public <Y> CollectionJoin<E, Y> join(CollectionAttribute<? super E, Y> collection, JoinType jt) {
throw illegalJoin();
}
@Override
public <Y> SetJoin<E, Y> join(javax.persistence.metamodel.SetAttribute<? super E, Y> set, JoinType jt) {
throw illegalJoin();
}
@Override
public <Y> ListJoin<E, Y> join(ListAttribute<? super E, Y> list, JoinType jt) {
throw illegalJoin();
}
@Override
public <L, W> MapJoin<E, L, W> join(MapAttribute<? super E, L, W> map, JoinType jt) {
throw illegalJoin();
}
@Override
public <E,Y> Join<E, Y> join(String attributeName, JoinType jt) {
throw illegalJoin();
}
@Override
public <E,Y> CollectionJoin<E, Y> joinCollection(String attributeName, JoinType jt) {
throw illegalJoin();
}
@Override
public <E,Y> ListJoin<E, Y> joinList(String attributeName, JoinType jt) {
throw illegalJoin();
}
@Override
public <E, L, W> MapJoin<E, L, W> joinMap(String attributeName, JoinType jt) {
throw illegalJoin();
}
@Override
public <E,Y> SetJoin<E, Y> joinSet(String attributeName, JoinType jt) {
throw illegalJoin();
}
@Override
public <Y> Fetch<E, Y> fetch(SingularAttribute<? super E, Y> singularAttribute) {
throw illegalFetch();
}
private BasicPathUsageException illegalFetch() {
return new BasicPathUsageException( "Basic collection cannot be source of a fetch", getAttribute() );
}
@Override
public <Y> Fetch<E, Y> fetch(SingularAttribute<? super E, Y> attribute, JoinType jt) {
throw illegalFetch();
}
@Override
public <Y> Fetch<E, Y> fetch(PluralAttribute<? super E, ?, Y> pluralAttribute) {
throw illegalFetch();
}
@Override
public <Y> Fetch<E, Y> fetch(PluralAttribute<? super E, ?, Y> pluralAttribute, JoinType jt) {
throw illegalFetch();
}
@Override
public <X, Y> Fetch<X, Y> fetch(String attributeName) {
throw illegalFetch();
}
@Override
public <X, Y> Fetch<X, Y> fetch(String attributeName, JoinType jt) {
throw illegalFetch();
}
}

View File

@ -1,90 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
* third-party contributors as indicated by either @author tags or express
* copyright attribution statements applied by the authors. All
* third-party contributions are distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.ejb.criteria;
import java.io.Serializable;
import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.From;
import javax.persistence.metamodel.CollectionAttribute;
import org.hibernate.ejb.criteria.JoinImplementors.CollectionJoinImplementor;
/**
* Represents a join to a persistent collection, defined as type {@link java.util.Collection}, whose elements
* are basic type.
*
* @author Steve Ebersole
*/
public class BasicCollectionJoinImpl<O,E>
extends AbstractBasicPluralJoin<O,java.util.Collection<E>,E>
implements JoinImplementors.CollectionJoinImplementor<O,E>, Serializable {
public BasicCollectionJoinImpl(
CriteriaBuilderImpl criteriaBuilder,
Class<E> javaType,
PathImpl<O> lhs,
CollectionAttribute<? super O, E> joinProperty,
JoinType joinType) {
super( criteriaBuilder, javaType, lhs, joinProperty, joinType);
}
@Override
public CollectionAttribute<? super O, E> getAttribute() {
return (CollectionAttribute<? super O, E>) super.getAttribute();
}
@Override
public CollectionAttribute<? super O, E> getModel() {
return getAttribute();
}
@Override
public CollectionJoinImplementor<O, E> correlateTo(CriteriaSubqueryImpl subquery) {
BasicCollectionJoinImpl<O,E> correlation = new BasicCollectionJoinImpl<O,E>(
queryBuilder(),
getJavaType(),
(PathImpl<O>) getParentPath(),
getModel(),
getJoinType()
);
correlation.defineJoinScope( subquery.getJoinScope() );
correlation.correlationParent = this;
return correlation;
}
private From<O, E> correlationParent;
/**
* {@inheritDoc}
*/
public boolean isCorrelated() {
return false;
}
/**
* {@inheritDoc}
*/
public From<O, E> getCorrelationParent() {
return null;
}
}

View File

@ -1,171 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
* third-party contributors as indicated by either @author tags or express
* copyright attribution statements applied by the authors. All
* third-party contributions are distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.ejb.criteria;
import java.io.Serializable;
import java.util.Map;
import java.util.Map.Entry;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.From;
import javax.persistence.metamodel.MapAttribute;
import javax.persistence.metamodel.Type.PersistenceType;
import org.hibernate.ejb.criteria.JoinImplementors.MapJoinImplementor;
/**
* Represents a join to a persistent collection, defined as type {@link java.util.Map}, whose elements
* are associations.
*
* @param <O> The map owner
* @param <K> The map key
* @param <V> The map value
*
* @author Steve Ebersole
*/
public class BasicMapJoinImpl<O,K,V>
extends AbstractBasicPluralJoin<O,java.util.Map<K,V>,V>
implements JoinImplementors.MapJoinImplementor<O,K,V>, Serializable {
public BasicMapJoinImpl(
CriteriaBuilderImpl criteriaBuilder,
Class<V> javaType,
PathImpl<O> lhs,
MapAttribute<? super O, K, V> joinProperty,
JoinType joinType) {
super( criteriaBuilder, javaType, lhs, joinProperty, joinType );
}
@Override
public MapAttribute<? super O, K, V> getAttribute() {
return (MapAttribute<? super O, K, V>) super.getAttribute();
}
@Override
public MapAttribute<? super O, K, V> getModel() {
return getAttribute();
}
/**
* {@inheritDoc}
*/
public Join<Map<K, V>, K> joinKey() {
return joinKey( DEFAULT_JOIN_TYPE );
}
/**
* {@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() );
}
if ( jt.equals( JoinType.RIGHT ) ) {
throw new UnsupportedOperationException( "RIGHT JOIN not supported" );
}
final MapKeyHelpers.MapPath<K,V> source = new MapKeyHelpers.MapPath<K,V>(
queryBuilder(),
getAttribute().getJavaType(),
this,
getAttribute(),
getParentPath().getModel()
);
final MapKeyHelpers.MapKeyAttribute attribute = new MapKeyHelpers.MapKeyAttribute( queryBuilder(), getAttribute() );
return new MapKeyHelpers.MapKeyJoin<K,V>(
queryBuilder(),
source,
attribute,
jt
);
}
/**
* {@inheritDoc}
*/
@SuppressWarnings({ "unchecked" })
public Path<K> key() {
final MapKeyHelpers.MapPath<K,V> source = new MapKeyHelpers.MapPath<K,V>(
queryBuilder(),
getAttribute().getJavaType(),
this,
getAttribute(),
getParentPath().getModel()
);
final MapKeyHelpers.MapKeyAttribute attribute = new MapKeyHelpers.MapKeyAttribute( queryBuilder(), getAttribute() );
return new MapKeyHelpers.MapKeyPath( queryBuilder(), source, attribute );
}
/**
* {@inheritDoc}
*/
public Path<V> value() {
// API docs explicitly say value() should simply return this;
return this;
}
/**
* {@inheritDoc}
*/
@SuppressWarnings({ "unchecked" })
public Expression<Entry<K, V>> entry() {
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(),
getJavaType(),
(PathImpl<O>) getParentPath(),
getAttribute(),
getJoinType()
);
correlation.defineJoinScope( subquery.getJoinScope() );
correlation.correlationParent = this;
return correlation;
}
/**
* {@inheritDoc}
*/
public boolean isCorrelated() {
return getCorrelationParent() != null;
}
/**
* {@inheritDoc}
*/
public From<O, V> getCorrelationParent() {
return correlationParent;
}
}

View File

@ -1,90 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
* third-party contributors as indicated by either @author tags or express
* copyright attribution statements applied by the authors. All
* third-party contributions are distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.ejb.criteria;
import java.io.Serializable;
import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.From;
import javax.persistence.metamodel.SetAttribute;
import org.hibernate.ejb.criteria.JoinImplementors.SetJoinImplementor;
/**
* Represents a join to a persistent collection, defined as type {@link java.util.Set}, whose elements
* are basic type.
*
* @author Steve Ebersole
*/
public class BasicSetJoinImpl<O,E>
extends AbstractBasicPluralJoin<O,java.util.Set<E>,E>
implements JoinImplementors.SetJoinImplementor<O,E>, Serializable {
public BasicSetJoinImpl(
CriteriaBuilderImpl criteriaBuilder,
Class<E> javaType,
PathImpl<O> lhs,
SetAttribute<? super O, ?> joinProperty,
JoinType joinType) {
super( criteriaBuilder, javaType, lhs, joinProperty, joinType );
}
@Override
public SetAttribute<? super O, E> getAttribute() {
return (SetAttribute<? super O, E>) super.getAttribute();
}
@Override
public SetAttribute<? super O, E> getModel() {
return getAttribute();
}
@Override
public SetJoinImplementor<O, E> correlateTo(CriteriaSubqueryImpl subquery) {
BasicSetJoinImpl<O,E> correlation = new BasicSetJoinImpl<O,E>(
queryBuilder(),
getJavaType(),
(PathImpl<O>) getParentPath(),
getAttribute(),
getJoinType()
);
correlation.defineJoinScope( subquery.getJoinScope() );
correlation.correlationParent = this;
return correlation;
}
private From<O, E> correlationParent;
/**
* {@inheritDoc}
*/
public boolean isCorrelated() {
return getCorrelationParent() != null;
}
/**
* {@inheritDoc}
*/
public From<O, E> getCorrelationParent() {
return correlationParent;
}
}

View File

@ -1,99 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
* third-party contributors as indicated by either @author tags or express
* copyright attribution statements applied by the authors. All
* third-party contributions are distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.ejb.criteria;
import java.io.Serializable;
import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.From;
import javax.persistence.metamodel.CollectionAttribute;
import javax.persistence.metamodel.ManagedType;
import org.hibernate.ejb.criteria.JoinImplementors.CollectionJoinImplementor;
/**
* Represents a join to a persistent collection, defined as type {@link java.util.Collection}, whose elements
* are associations.
*
* @author Steve Ebersole
*/
public class CollectionJoinImpl<O,E>
extends JoinImpl<O,E>
implements JoinImplementors.CollectionJoinImplementor<O,E>, Serializable {
public CollectionJoinImpl(
CriteriaBuilderImpl criteriaBuilder,
Class<E> javaType,
PathImpl<O> lhs,
CollectionAttribute<? super O, ?> joinProperty,
JoinType joinType) {
super( criteriaBuilder, javaType, lhs, joinProperty, joinType);
}
@Override
public CollectionAttribute<? super O, E> getAttribute() {
return (CollectionAttribute<? super O, E>) super.getAttribute();
}
@Override
public CollectionAttribute<? super O, E> getModel() {
return getAttribute();
}
@Override
protected ManagedType<E> getManagedType() {
return ( ManagedType<E> ) getAttribute().getElementType();
}
@Override
@SuppressWarnings({ "unchecked" })
public CollectionJoinImplementor<O, E> correlateTo(CriteriaSubqueryImpl subquery) {
CollectionJoinImpl<O,E> correlation = new CollectionJoinImpl<O,E>(
queryBuilder(),
getJavaType(),
(PathImpl<O>) getParentPath(),
getAttribute(),
getJoinType()
);
correlation.defineJoinScope( subquery.getJoinScope() );
correlation.correlationParent = this;
return correlation;
}
private From<O, E> correlationParent;
/**
* {@inheritDoc}
*/
public boolean isCorrelated() {
return false;
}
/**
* {@inheritDoc}
*/
public From<O, E> getCorrelationParent() {
return null;
}
}

View File

@ -0,0 +1,40 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.ejb.criteria;
import javax.persistence.criteria.CollectionJoin;
/**
* Specialization of {@link JoinImplementor} for {@link java.util.Collection} typed attribute joins
*
* @author Steve Ebersole
*/
public interface CollectionJoinImplementor<Z,X> extends JoinImplementor<Z,X>, CollectionJoin<Z,X> {
/**
* {@inheritDoc}
* <p/>
* Refined return type
*/
public CollectionJoinImplementor<Z,X> correlateTo(CriteriaSubqueryImpl subquery);
}

View File

@ -45,7 +45,6 @@ import javax.persistence.Tuple;
import org.hibernate.ejb.EntityManagerFactoryImpl;
import org.hibernate.ejb.criteria.expression.BinaryArithmeticOperation;
import org.hibernate.ejb.criteria.expression.CoalesceExpression;
import org.hibernate.ejb.criteria.expression.CollectionExpression;
import org.hibernate.ejb.criteria.expression.CompoundSelectionImpl;
import org.hibernate.ejb.criteria.expression.ConcatExpression;
import org.hibernate.ejb.criteria.expression.ParameterExpressionImpl;
@ -70,6 +69,7 @@ import org.hibernate.ejb.criteria.expression.function.SqrtFunction;
import org.hibernate.ejb.criteria.expression.function.SubstringFunction;
import org.hibernate.ejb.criteria.expression.function.TrimFunction;
import org.hibernate.ejb.criteria.expression.function.UpperFunction;
import org.hibernate.ejb.criteria.path.PluralAttributePath;
import org.hibernate.ejb.criteria.predicate.BooleanAssertionPredicate;
import org.hibernate.ejb.criteria.predicate.BooleanExpressionPredicate;
import org.hibernate.ejb.criteria.predicate.NullnessPredicate;
@ -1275,8 +1275,8 @@ public class CriteriaBuilderImpl implements CriteriaBuilder, Serializable {
if ( LiteralExpression.class.isInstance(exp) ) {
return size( ( (LiteralExpression<C>) exp ).getLiteral() );
}
else if ( CollectionExpression.class.isInstance(exp) ) {
return new SizeOfCollectionExpression<C>(this, (CollectionExpression<C>) exp );
else if ( PluralAttributePath.class.isInstance(exp) ) {
return new SizeOfCollectionExpression<C>(this, (PluralAttributePath<C>) exp );
}
// TODO : what other specific types? any?
throw new IllegalArgumentException("unknown collection expression type [" + exp.getClass().getName() + "]" );
@ -1302,11 +1302,8 @@ public class CriteriaBuilderImpl implements CriteriaBuilder, Serializable {
*/
@SuppressWarnings({ "unchecked" })
public <C extends Collection<?>> Predicate isEmpty(Expression<C> collectionExpression) {
if ( CollectionExpression.class.isInstance(collectionExpression) ) {
return new IsEmptyPredicate(
this,
(CollectionExpression<C>) collectionExpression
);
if ( PluralAttributePath.class.isInstance(collectionExpression) ) {
return new IsEmptyPredicate( this, (PluralAttributePath<C>) collectionExpression );
}
// TODO : what other specific types? any?
throw new IllegalArgumentException(
@ -1325,7 +1322,7 @@ public class CriteriaBuilderImpl implements CriteriaBuilder, Serializable {
* {@inheritDoc}
*/
public <E, C extends Collection<E>> Predicate isMember(E e, Expression<C> collectionExpression) {
if ( ! CollectionExpression.class.isInstance(collectionExpression) ) {
if ( ! PluralAttributePath.class.isInstance( collectionExpression ) ) {
throw new IllegalArgumentException(
"unknown collection expression type [" + collectionExpression.getClass().getName() + "]"
);
@ -1333,7 +1330,7 @@ public class CriteriaBuilderImpl implements CriteriaBuilder, Serializable {
return new MemberOfPredicate<E, C>(
this,
e,
(CollectionExpression<C>)collectionExpression
(PluralAttributePath<C>)collectionExpression
);
}
@ -1348,7 +1345,7 @@ public class CriteriaBuilderImpl implements CriteriaBuilder, Serializable {
* {@inheritDoc}
*/
public <E, C extends Collection<E>> Predicate isMember(Expression<E> elementExpression, Expression<C> collectionExpression) {
if ( ! CollectionExpression.class.isInstance(collectionExpression) ) {
if ( ! PluralAttributePath.class.isInstance( collectionExpression ) ) {
throw new IllegalArgumentException(
"unknown collection expression type [" + collectionExpression.getClass().getName() + "]"
);
@ -1356,7 +1353,7 @@ public class CriteriaBuilderImpl implements CriteriaBuilder, Serializable {
return new MemberOfPredicate<E, C>(
this,
elementExpression,
(CollectionExpression<C>)collectionExpression
(PluralAttributePath<C>)collectionExpression
);
}

View File

@ -39,10 +39,9 @@ import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.persistence.criteria.SetJoin;
import javax.persistence.criteria.Subquery;
import javax.persistence.criteria.From;
import javax.persistence.metamodel.EntityType;
import org.hibernate.ejb.criteria.FromImpl.JoinScope;
import org.hibernate.ejb.criteria.expression.ExpressionImpl;
import org.hibernate.ejb.criteria.path.RootImpl;
/**
* The Hibernate implementation of the JPA {@link Subquery} contract. Mostlty a set of delegation to its internal
@ -57,7 +56,7 @@ public class CriteriaSubqueryImpl<T> extends ExpressionImpl<T> implements Subque
private Expression<T> selection;
private Set<Join<?, ?>> correlatedJoins = new HashSet<Join<?,?>>();
private final FromImpl.JoinScope joinScope = new FromImpl.JoinScope() {
private final FromImplementor.JoinScope joinScope = new FromImplementor.JoinScope() {
public void addJoin(Join join) {
correlatedJoins.add( join );
}
@ -65,14 +64,6 @@ public class CriteriaSubqueryImpl<T> extends ExpressionImpl<T> implements Subque
public void addFetch(Fetch fetch) {
throw new UnsupportedOperationException( "Cannot define fetch from a subquery correlation" );
}
public boolean isCorrelated() {
return true;
}
public From getCorrelationParent() {
return null;
}
};
public CriteriaSubqueryImpl(
@ -89,7 +80,7 @@ public class CriteriaSubqueryImpl<T> extends ExpressionImpl<T> implements Subque
*
* @return The subquery's join scope.
*/
public JoinScope getJoinScope() {
public FromImplementor.JoinScope getJoinScope() {
return joinScope;
}
@ -260,35 +251,35 @@ public class CriteriaSubqueryImpl<T> extends ExpressionImpl<T> implements Subque
* {@inheritDoc}
*/
public <X, Y> Join<X, Y> correlate(Join<X, Y> source) {
return ( ( JoinImplementors.JoinImplementor<X,Y> ) source ).correlateTo( this );
return ( (JoinImplementor<X,Y>) source ).correlateTo( this );
}
/**
* {@inheritDoc}
*/
public <X, Y> CollectionJoin<X, Y> correlate(CollectionJoin<X, Y> source) {
return ( ( JoinImplementors.CollectionJoinImplementor<X,Y> ) source ).correlateTo( this );
return ( (CollectionJoinImplementor<X,Y>) source ).correlateTo( this );
}
/**
* {@inheritDoc}
*/
public <X, Y> SetJoin<X, Y> correlate(SetJoin<X, Y> source) {
return ( ( JoinImplementors.SetJoinImplementor<X,Y> ) source ).correlateTo( this );
return ( (SetJoinImplementor<X,Y>) source ).correlateTo( this );
}
/**
* {@inheritDoc}
*/
public <X, Y> ListJoin<X, Y> correlate(ListJoin<X, Y> source) {
return ( ( JoinImplementors.ListJoinImplementor<X,Y> ) source ).correlateTo( this );
return ( (ListJoinImplementor<X,Y>) source ).correlateTo( this );
}
/**
* {@inheritDoc}
*/
public <X, K, V> MapJoin<X, K, V> correlate(MapJoin<X, K, V> source) {
return ( ( JoinImplementors.MapJoinImplementor<X, K, V> ) source ).correlateTo( this );
return ( (MapJoinImplementor<X, K, V>) source ).correlateTo( this );
}
/**

View File

@ -0,0 +1,50 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.ejb.criteria;
import java.io.Serializable;
import javax.persistence.criteria.Fetch;
import javax.persistence.criteria.From;
import javax.persistence.criteria.Join;
/**
* Implementation contract for the JPA {@link From} interface.
*
* @author Steve Ebersole
*/
public interface FromImplementor<Z,X> extends PathImplementor<X>, From<Z,X> {
public void prepareAlias(CriteriaQueryCompiler.RenderingContext renderingContext);
public String renderTableExpression(CriteriaQueryCompiler.RenderingContext renderingContext);
/**
* Helper contract used to define who/what keeps track of joins and fetches made from this <tt>FROM</tt>.
*/
public static interface JoinScope<X> extends Serializable {
public void addJoin(Join<X, ?> join);
public void addFetch(Fetch<X,?> fetch);
}
public FromImplementor<Z,X> correlateTo(CriteriaSubqueryImpl subquery);
public void prepareCorrelationDelegate(JoinScope<X> joinScope, FromImplementor<Z,X> parent);
}

View File

@ -0,0 +1,43 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.ejb.criteria;
/**
* Represents an illegal attempt to dereference from a {@link #getPathSource() path source} which
* cannot be dereferenced.
*
* @author Steve Ebersole
*/
public class IllegalDereferenceException extends RuntimeException {
private final PathSource pathSource;
public IllegalDereferenceException(PathSource pathSource) {
super( "Illegal attempt to dereference path source [" + pathSource.getPathIdentifier() + "]" );
this.pathSource = pathSource;
}
public PathSource getPathSource() {
return pathSource;
}
}

View File

@ -1,144 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
* third-party contributors as indicated by either @author tags or express
* copyright attribution statements applied by the authors. All
* third-party contributions are distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.ejb.criteria;
import java.io.Serializable;
import javax.persistence.criteria.From;
import javax.persistence.criteria.JoinType;
import javax.persistence.metamodel.Attribute;
import javax.persistence.metamodel.ManagedType;
import javax.persistence.metamodel.Bindable;
import javax.persistence.metamodel.SingularAttribute;
import javax.persistence.metamodel.EmbeddableType;
/**
* Models a non-collection property join.
*
* @author Steve Ebersole
*/
public class JoinImpl<Z, X>
extends FromImpl<Z, X>
implements JoinImplementors.JoinImplementor<Z,X>, Serializable {
// TODO : keep track or whether any non-identifier properties get dereferenced
// for join optimization like in HQL
// TODO : do we need (or is it easier with) a separate "component join impl"?
// TODO : cleanup these ctors, ugh...
private final ManagedType<X> managedType;
private final JoinType joinType;
@SuppressWarnings({ "unchecked" })
public JoinImpl(
CriteriaBuilderImpl criteriaBuilder,
Class<X> javaType,
PathImpl<Z> lhs,
Attribute<? super Z, ?> joinProperty,
JoinType joinType) {
super(
criteriaBuilder,
javaType,
lhs,
joinProperty,
( Bindable<X> ) ( Attribute.PersistentAttributeType.EMBEDDED == joinProperty.getPersistentAttributeType()
? joinProperty
: criteriaBuilder.getEntityManagerFactory().getMetamodel().managedType( javaType ))
);
this.managedType = getManagedType();
this.joinType = joinType;
}
@SuppressWarnings({ "unchecked" })
protected ManagedType<X> getManagedType() {
Bindable<X> model = getModel();
return Bindable.BindableType.ENTITY_TYPE == model.getBindableType()
? (ManagedType<X>) model
: (EmbeddableType<X>) ( (SingularAttribute) model ).getType();
}
/**
* {@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();
}
/**
* {@inheritDoc}
*/
public JoinType getJoinType() {
return joinType;
}
@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(),
getJavaType(),
(PathImpl<Z>)getParentPath(),
getAttribute(),
getJoinType()
);
correlation.defineJoinScope( subquery.getJoinScope() );
correlation.correlationParent = this;
return correlation;
}
private From<Z,X> correlationParent;
/**
* {@inheritDoc}
*/
public boolean isCorrelated() {
return false;
}
/**
* {@inheritDoc}
*/
public From<Z,X> getCorrelationParent() {
return correlationParent;
}
public String renderTableExpression(CriteriaQueryCompiler.RenderingContext renderingContext) {
prepareAlias( renderingContext );
( (FromImpl) getParent() ).prepareAlias( renderingContext );
return getParent().getAlias() + '.' + getAttribute().getName() + " as " + getAlias();
}
}

View File

@ -0,0 +1,42 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.ejb.criteria;
import javax.persistence.criteria.Fetch;
import javax.persistence.criteria.Join;
/**
* Consolidates the {@link Join} and {@link Fetch} hierarchies since that is how we implement them.
* This allows us to treat them polymorphically.
*
* @author Steve Ebersole
*/
public interface JoinImplementor<Z,X> extends Join<Z,X>, Fetch<Z,X>, FromImplementor<Z,X> {
/**
* {@inheritDoc}
* <p/>
* Refined return type
*/
public JoinImplementor<Z,X> correlateTo(CriteriaSubqueryImpl subquery);
}

View File

@ -1,65 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
* third-party contributors as indicated by either @author tags or express
* copyright attribution statements applied by the authors. All
* third-party contributions are distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.ejb.criteria;
import javax.persistence.criteria.CollectionJoin;
import javax.persistence.criteria.Fetch;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.ListJoin;
import javax.persistence.criteria.MapJoin;
import javax.persistence.criteria.SetJoin;
import javax.persistence.criteria.From;
/**
* Consolidates the {@link Join} and {@link Fetch} hierarchies since that is how we implement them.
* This allows us to treat them polymorphically.
*
* @author Steve Ebersole
*/
public interface JoinImplementors {
public static interface JoinImplementor<Z,X>
extends Join<Z,X>, Fetch<Z,X> {
public JoinImplementor<Z,X> correlateTo(CriteriaSubqueryImpl subquery);
}
public static interface CollectionJoinImplementor<Z,X>
extends JoinImplementor<Z,X>, CollectionJoin<Z,X>, Fetch<Z,X> {
public CollectionJoinImplementor<Z,X> correlateTo(CriteriaSubqueryImpl subquery);
}
public static interface SetJoinImplementor<Z,X>
extends JoinImplementor<Z,X>, SetJoin<Z,X>, Fetch<Z,X> {
public SetJoinImplementor<Z,X> correlateTo(CriteriaSubqueryImpl subquery);
}
public static interface ListJoinImplementor<Z,X>
extends JoinImplementor<Z,X>, ListJoin<Z,X>, Fetch<Z,X> {
public ListJoinImplementor<Z,X> correlateTo(CriteriaSubqueryImpl subquery);
}
public static interface MapJoinImplementor<Z,K,V>
extends JoinImplementor<Z,V>, MapJoin<Z,K,V>, Fetch<Z,V> {
public MapJoinImplementor<Z,K,V> correlateTo(CriteriaSubqueryImpl subquery);
}
}

View File

@ -1,106 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
* third-party contributors as indicated by either @author tags or express
* copyright attribution statements applied by the authors. All
* third-party contributions are distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.ejb.criteria;
import java.io.Serializable;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.From;
import javax.persistence.metamodel.ListAttribute;
import javax.persistence.metamodel.ManagedType;
import org.hibernate.ejb.criteria.JoinImplementors.ListJoinImplementor;
import org.hibernate.ejb.criteria.expression.ListIndexExpression;
/**
* Represents a join to a persistent collection, defined as type {@link java.util.List}, whose elements
* are associations.
*
* @author Steve Ebersole
*/
public class ListJoinImpl<O,E>
extends JoinImpl<O,E>
implements JoinImplementors.ListJoinImplementor<O,E>, Serializable {
public ListJoinImpl(
CriteriaBuilderImpl criteriaBuilder,
Class<E> javaType,
PathImpl<O> lhs,
ListAttribute<? super O, ?> joinProperty,
JoinType joinType) {
super( criteriaBuilder, javaType, lhs, joinProperty, joinType );
}
@Override
public ListAttribute<? super O, E> getAttribute() {
return (ListAttribute<? super O, E>) super.getAttribute();
}
@Override
public ListAttribute<? super O, E> getModel() {
return getAttribute();
}
@Override
protected ManagedType<E> getManagedType() {
return ( ManagedType<E> ) getAttribute().getElementType();
}
/**
* {@inheritDoc}
*/
public Expression<Integer> index() {
return new ListIndexExpression( queryBuilder(), this, getAttribute() );
}
@Override
@SuppressWarnings({ "unchecked" })
public ListJoinImplementor<O, E> correlateTo(CriteriaSubqueryImpl subquery) {
ListJoinImpl<O,E> correlation = new ListJoinImpl<O,E>(
queryBuilder(),
getJavaType(),
(PathImpl<O>) getParentPath(),
getAttribute(),
getJoinType()
);
correlation.defineJoinScope( subquery.getJoinScope() );
correlation.correlationParent = this;
return correlation;
}
private From<O, E> correlationParent;
/**
* {@inheritDoc}
*/
public boolean isCorrelated() {
return getCorrelationParent() != null;
}
/**
* {@inheritDoc}
*/
public From<O, E> getCorrelationParent() {
return correlationParent;
}
}

View File

@ -0,0 +1,40 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.ejb.criteria;
import javax.persistence.criteria.ListJoin;
/**
* Specialization of {@link JoinImplementor} for {@link java.util.List} typed attribute joins
*
* @author Steve Ebersole
*/
public interface ListJoinImplementor<Z,X> extends JoinImplementor<Z,X>, ListJoin<Z,X> {
/**
* {@inheritDoc}
* <p/>
* Refined return type
*/
public ListJoinImplementor<Z,X> correlateTo(CriteriaSubqueryImpl subquery);
}

View File

@ -1,171 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
* third-party contributors as indicated by either @author tags or express
* copyright attribution statements applied by the authors. All
* third-party contributions are distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.ejb.criteria;
import java.io.Serializable;
import java.util.Map;
import java.util.Map.Entry;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.From;
import javax.persistence.metamodel.MapAttribute;
import javax.persistence.metamodel.ManagedType;
import javax.persistence.metamodel.Type.PersistenceType;
import org.hibernate.ejb.criteria.JoinImplementors.MapJoinImplementor;
/**
* Represents a join to a persistent collection, defined as type {@link java.util.Map}, whose elements
* are associations.
*
* @author Steve Ebersole
*/
public class MapJoinImpl<O,K,V>
extends JoinImpl<O,V>
implements JoinImplementors.MapJoinImplementor<O,K,V>, Serializable {
public MapJoinImpl(
CriteriaBuilderImpl criteriaBuilder,
Class<V> javaType,
PathImpl<O> lhs,
MapAttribute<? super O, K, V> joinProperty,
JoinType joinType) {
super( criteriaBuilder, javaType, lhs, joinProperty, joinType);
}
@Override
public MapAttribute<? super O, K, V> getAttribute() {
return (MapAttribute<? super O, K, V>) super.getAttribute();
}
@Override
public MapAttribute<? super O, K, V> getModel() {
return getAttribute();
}
@Override
protected ManagedType<V> getManagedType() {
return ( ManagedType<V> ) getAttribute().getElementType();
}
/**
* {@inheritDoc}
*/
public Join<Map<K, V>, K> joinKey() {
return joinKey( DEFAULT_JOIN_TYPE );
}
/**
* {@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() );
}
if ( jt.equals( JoinType.RIGHT ) ) {
throw new UnsupportedOperationException( "RIGHT JOIN not supported" );
}
final MapKeyHelpers.MapPath<K,V> mapKeySource = new MapKeyHelpers.MapPath<K,V>(
queryBuilder(),
getAttribute().getJavaType(),
this,
getAttribute(),
getParentPath().getModel()
);
final MapKeyHelpers.MapKeyAttribute mapKeyAttribute = new MapKeyHelpers.MapKeyAttribute( queryBuilder(), getAttribute() );
return new MapKeyHelpers.MapKeyJoin<K,V>(
queryBuilder(),
mapKeySource,
mapKeyAttribute,
jt
);
}
/**
* {@inheritDoc}
*/
@SuppressWarnings({ "unchecked" })
public Path<K> key() {
final MapKeyHelpers.MapPath<K,V> mapKeySource = new MapKeyHelpers.MapPath<K,V>(
queryBuilder(),
getAttribute().getJavaType(),
this,
getAttribute(),
getParentPath().getModel()
);
final MapKeyHelpers.MapKeyAttribute mapKeyAttribute = new MapKeyHelpers.MapKeyAttribute( queryBuilder(), getAttribute() );
return new MapKeyHelpers.MapKeyPath( queryBuilder(), mapKeySource, mapKeyAttribute );
}
/**
* {@inheritDoc}
*/
public Path<V> value() {
return this;
}
/**
* {@inheritDoc}
*/
@SuppressWarnings({ "unchecked" })
public Expression<Entry<K, V>> entry() {
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(),
getJavaType(),
(PathImpl<O>) getParentPath(),
getAttribute(),
getJoinType()
);
correlation.defineJoinScope( subquery.getJoinScope() );
correlation.correlationParent = this;
return correlation;
}
/**
* {@inheritDoc}
*/
public boolean isCorrelated() {
return getCorrelationParent() != null;
}
/**
* {@inheritDoc}
*/
public From<O, V> getCorrelationParent() {
return correlationParent;
}
}

View File

@ -0,0 +1,40 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.ejb.criteria;
import javax.persistence.criteria.MapJoin;
/**
* Specialization of {@link JoinImplementor} for {@link java.util.Map} typed attribute joins
*
* @author Steve Ebersole
*/
public interface MapJoinImplementor<Z,K,V> extends JoinImplementor<Z,V>, MapJoin<Z,K,V> {
/**
* {@inheritDoc}
* <p/>
* Refined return type
*/
public MapJoinImplementor<Z,K,V> correlateTo(CriteriaSubqueryImpl subquery);
}

View File

@ -1,170 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
* third-party contributors as indicated by either @author tags or express
* copyright attribution statements applied by the authors. All
* third-party contributions are distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.ejb.criteria;
import java.io.Serializable;
import java.util.Collection;
import java.util.Map;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Path;
import javax.persistence.metamodel.Attribute;
import javax.persistence.metamodel.Bindable;
import javax.persistence.metamodel.MapAttribute;
import javax.persistence.metamodel.PluralAttribute;
import javax.persistence.metamodel.SingularAttribute;
import org.hibernate.ejb.criteria.expression.ExpressionImpl;
/**
* A {@link Path} models an individual portion of a path expression.
*
* @author Steve Ebersole
*/
public class PathImpl<X> extends ExpressionImpl<X> implements Path<X>, Serializable {
private final PathImpl<?> origin;
private final Attribute<?,?> attribute;
private Object model;
/**
* Constructs a path.
*
* @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(
CriteriaBuilderImpl criteriaBuilder,
Class<X> javaType,
PathImpl<?> origin,
Attribute<?,?> attribute,
Object model) {
super( criteriaBuilder, javaType );
this.origin = origin;
this.attribute = attribute;
this.model = model;
}
/**
* {@inheritDoc}
*/
public PathImpl<?> getParentPath() {
return origin;
}
public Attribute<?, ?> getAttribute() {
return attribute;
}
/**
* {@inheritDoc}
*/
@SuppressWarnings({ "unchecked" })
public Bindable<X> getModel() {
if ( model == null ) {
throw new IllegalStateException( this + " represents a basic path and not a bindable" );
}
return (Bindable<X>)model;
}
/**
* {@inheritDoc}
* <p/>
* Subclasses override this appropriately, but here we simply throw
* an {@link IllegalStateException}
*/
public Expression<Class<? extends X>> type() {
throw new BasicPathUsageException( "type() is not applicable to primitive paths.", getAttribute() );
}
/**
* {@inheritDoc}
* <p/>
* Subclasses override this appropriately, but here we simply throw
* an {@link IllegalStateException}
*/
public <Y> Path<Y> get(SingularAttribute<? super X, Y> attribute) {
throw illegalDereference();
}
private BasicPathUsageException illegalDereference() {
return new BasicPathUsageException( "Primitive path cannot be de-referenced", getAttribute() );
}
/**
* {@inheritDoc}
* <p/>
* Subclasses override this appropriately, but here we simply throw
* an {@link IllegalStateException}
*/
public <E, C extends Collection<E>> Expression<C> get(PluralAttribute<X, C, E> collection) {
throw illegalDereference();
}
/**
* {@inheritDoc}
* <p/>
* Subclasses override this appropriately, but here we simply throw
* an {@link IllegalStateException}
*/
public <K, V, M extends Map<K, V>> Expression<M> get(MapAttribute<X, K, V> map) {
throw illegalDereference();
}
/**
* {@inheritDoc}
* <p/>
* Subclasses override this appropriately, but here we simply throw
* an {@link IllegalStateException}
*/
public <Y> Path<Y> get(String attributeName) {
throw illegalDereference();
}
public void registerParameters(ParameterRegistry registry) {
// 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

@ -31,15 +31,7 @@ import javax.persistence.metamodel.Attribute;
*
* @author Steve Ebersole
*/
public interface PathImplementor<X> extends ExpressionImplementor<X>, Path<X> {
/**
* Get the string representation of this path as a navigation from one of the
* queries <tt>identification variables</tt>
*
* @return The path's identifier.
*/
public String getPathIdentifier();
public interface PathImplementor<X> extends ExpressionImplementor<X>, Path<X>, PathSource<X>, Renderable {
/**
* Retrieve reference to the attribute this path represents.
*

View File

@ -1,10 +1,10 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
* third-party contributors as indicated by either @author tags or express
* copyright attribution statements applied by the authors. All
* third-party contributions are distributed under license by Red Hat Inc.
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
@ -23,12 +23,21 @@
*/
package org.hibernate.ejb.criteria;
import javax.persistence.criteria.Path;
/**
* Common contract for things which map to a table expression in a <tt>SQL FROM clause</tt>.
* Implementation contract for things which can be the source (parent, left-hand-side, etc) of a path
*
* @author Steve Ebersole
*/
public interface TableExpressionMapper {
public interface PathSource<X> extends Path<X> {
public void prepareAlias(CriteriaQueryCompiler.RenderingContext renderingContext);
public String renderTableExpression(CriteriaQueryCompiler.RenderingContext renderingContext);
/**
* 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();
}

View File

@ -44,6 +44,8 @@ import javax.persistence.criteria.Fetch;
import javax.persistence.criteria.JoinType;
import javax.persistence.metamodel.EntityType;
import org.hibernate.ejb.criteria.path.RootImpl;
/**
* Models basic query structure. Used as a delegate in implementing both
* {@link org.hibernate.criterion.CriteriaQuery} and
@ -222,9 +224,9 @@ public class QueryStructure<T> implements Serializable {
jpaqlQuery.append( " from " );
String sep = "";
for ( Root root : getRoots() ) {
( (TableExpressionMapper) root ).prepareAlias( renderingContext );
( (FromImplementor) root ).prepareAlias( renderingContext );
jpaqlQuery.append( sep );
jpaqlQuery.append( ( ( TableExpressionMapper ) root ).renderTableExpression( renderingContext ) );
jpaqlQuery.append( ( (FromImplementor) root ).renderTableExpression( renderingContext ) );
sep = ", ";
}
@ -264,9 +266,9 @@ public class QueryStructure<T> implements Serializable {
}
for ( Join join : joins ) {
( (TableExpressionMapper) join ).prepareAlias( renderingContext );
( (FromImplementor) join ).prepareAlias( renderingContext );
jpaqlQuery.append( renderJoinType( join.getJoinType() ) )
.append( ( ( TableExpressionMapper ) join ).renderTableExpression( renderingContext ) );
.append( ( (FromImplementor) join ).renderTableExpression( renderingContext ) );
renderJoins( jpaqlQuery, renderingContext, join.getJoins() );
renderFetches( jpaqlQuery, renderingContext, join.getFetches() );
}
@ -297,10 +299,10 @@ public class QueryStructure<T> implements Serializable {
}
for ( Fetch fetch : fetches ) {
( (TableExpressionMapper) fetch ).prepareAlias( renderingContext );
( (FromImplementor) fetch ).prepareAlias( renderingContext );
jpaqlQuery.append( renderJoinType( fetch.getJoinType() ) )
.append( "fetch " )
.append( ( ( TableExpressionMapper ) fetch ).renderTableExpression( renderingContext ) );
.append( ( (FromImplementor) fetch ).renderTableExpression( renderingContext ) );
renderFetches( jpaqlQuery, renderingContext, fetch.getFetches() );
}

View File

@ -1,70 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
* third-party contributors as indicated by either @author tags or express
* copyright attribution statements applied by the authors. All
* third-party contributions are distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.ejb.criteria;
import java.io.Serializable;
import javax.persistence.criteria.Root;
import javax.persistence.criteria.From;
import javax.persistence.metamodel.Attribute;
import javax.persistence.metamodel.EntityType;
/**
* Defines a <tt>query root</tt>.
*
* @author Steve Ebersole
*/
public class RootImpl<X> extends FromImpl<X,X> implements Root<X>, Serializable {
private RootImpl<X> correlationParent;
public RootImpl(
CriteriaBuilderImpl criteriaBuilder,
EntityType<X> model) {
super( criteriaBuilder, model );
}
@Override
public EntityType<X> getModel(){
return ( EntityType<X> ) super.getModel();
}
@Override
protected Attribute<X, ?> getAttribute(String name) {
return (Attribute<X, ?>) getModel().getAttribute( name );
}
public boolean isCorrelated() {
return getCorrelationParent() != null;
}
public From<X, X> getCorrelationParent() {
return correlationParent;
}
public RootImpl<X> correlateTo(CriteriaSubqueryImpl subquery) {
RootImpl<X> correlation = new RootImpl<X>( queryBuilder(), getModel() );
correlation.defineJoinScope( subquery.getJoinScope() );
correlation.correlationParent = this;
return correlation;
}
}

View File

@ -1,98 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
* third-party contributors as indicated by either @author tags or express
* copyright attribution statements applied by the authors. All
* third-party contributions are distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.ejb.criteria;
import java.io.Serializable;
import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.From;
import javax.persistence.metamodel.SetAttribute;
import javax.persistence.metamodel.ManagedType;
import org.hibernate.ejb.criteria.JoinImplementors.SetJoinImplementor;
/**
* Represents a join to a persistent collection, defined as type {@link java.util.Set}, whose elements
* are associations.
*
* @author Steve Ebersole
*/
public class SetJoinImpl<O,E>
extends JoinImpl<O,E>
implements JoinImplementors.SetJoinImplementor<O,E>, Serializable {
public SetJoinImpl(
CriteriaBuilderImpl criteriaBuilder,
Class<E> javaType,
PathImpl<O> lhs,
SetAttribute<? super O, ?> joinProperty,
JoinType joinType) {
super( criteriaBuilder, javaType, lhs, joinProperty, joinType);
}
@Override
public SetAttribute<? super O, E> getAttribute() {
return (SetAttribute<? super O, E>) super.getAttribute();
}
@Override
public SetAttribute<? super O, E> getModel() {
return getAttribute();
}
@Override
protected ManagedType<E> getManagedType() {
return ( ManagedType<E> ) getAttribute().getElementType();
}
@Override
@SuppressWarnings({ "unchecked" })
public SetJoinImplementor<O, E> correlateTo(CriteriaSubqueryImpl subquery) {
SetJoinImpl<O,E> correlation = new SetJoinImpl<O,E>(
queryBuilder(),
getJavaType(),
(PathImpl<O>) getParentPath(),
getAttribute(),
getJoinType()
);
correlation.defineJoinScope( subquery.getJoinScope() );
correlation.correlationParent = this;
return correlation;
}
private From<O, E> correlationParent;
/**
* {@inheritDoc}
*/
public boolean isCorrelated() {
return getCorrelationParent() != null;
}
/**
* {@inheritDoc}
*/
public From<O, E> getCorrelationParent() {
return correlationParent;
}
}

View File

@ -0,0 +1,40 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.ejb.criteria;
import javax.persistence.criteria.SetJoin;
/**
* Specialization of {@link JoinImplementor} for {@link java.util.Set} typed attribute joins
*
* @author Steve Ebersole
*/
public interface SetJoinImplementor<Z,X> extends JoinImplementor<Z,X>, SetJoin<Z,X> {
/**
* {@inheritDoc}
* <p/>
* Refined return type
*/
public SetJoinImplementor<Z,X> correlateTo(CriteriaSubqueryImpl subquery);
}

View File

@ -28,7 +28,8 @@ import javax.persistence.metamodel.ListAttribute;
import org.hibernate.ejb.criteria.ParameterRegistry;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaQueryCompiler;
import org.hibernate.ejb.criteria.PathImpl;
import org.hibernate.ejb.criteria.PathImplementor;
/**
* An expression for referring to the index of a list.
@ -36,21 +37,24 @@ import org.hibernate.ejb.criteria.PathImpl;
* @author Steve Ebersole
*/
public class ListIndexExpression extends ExpressionImpl<Integer> implements Serializable {
private final PathImpl origin;
private final ListAttribute<?,?> listAttribute;
private final PathImplementor origin;
private final ListAttribute listAttribute;
public ListIndexExpression(CriteriaBuilderImpl criteriaBuilder, PathImpl origin, ListAttribute<?,?> listAttribute) {
public ListIndexExpression(
CriteriaBuilderImpl criteriaBuilder,
PathImplementor origin,
ListAttribute listAttribute) {
super( criteriaBuilder, Integer.class );
this.origin = origin;
this.listAttribute = listAttribute;
}
public ListAttribute<?,?> getListAttribute() {
public ListAttribute getListAttribute() {
return listAttribute;
}
public void registerParameters(ParameterRegistry registry) {
// nothign to do
// nothing to do
}
public String render(CriteriaQueryCompiler.RenderingContext renderingContext) {

View File

@ -0,0 +1,81 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.ejb.criteria.expression;
import java.io.Serializable;
import java.util.Map;
import javax.persistence.criteria.Expression;
import javax.persistence.metamodel.MapAttribute;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaQueryCompiler;
import org.hibernate.ejb.criteria.ParameterRegistry;
import org.hibernate.ejb.criteria.PathImplementor;
import org.hibernate.ejb.criteria.Renderable;
/**
* TODO : javadoc
*
* @author Steve Ebersole
*/
public class MapEntryExpression<K,V>
extends ExpressionImpl<Map.Entry<K,V>>
implements Expression<Map.Entry<K,V>>, Serializable {
private final PathImplementor origin;
private final MapAttribute<?, K, V> attribute;
public MapEntryExpression(
CriteriaBuilderImpl criteriaBuilder,
Class<Map.Entry<K, V>> javaType,
PathImplementor origin,
MapAttribute<?, K, V> attribute) {
super( criteriaBuilder, javaType);
this.origin = origin;
this.attribute = attribute;
}
public MapAttribute<?, K, V> getAttribute() {
return attribute;
}
public void registerParameters(ParameterRegistry registry) {
// none to register
}
public String render(CriteriaQueryCompiler.RenderingContext renderingContext) {
// don't think this is valid 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()
+ '.'
+ ( (Renderable) getAttribute() ).renderProjection( renderingContext );
}
}

View File

@ -0,0 +1,54 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.ejb.criteria.expression;
import java.io.Serializable;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaQueryCompiler;
import org.hibernate.ejb.criteria.ParameterRegistry;
/**
* Used to construct the result of {@link javax.persistence.criteria.Path#type()}
*
* @author Steve Ebersole
*/
public class PathTypeExpression<T> extends ExpressionImpl<T> implements Serializable {
public PathTypeExpression(CriteriaBuilderImpl criteriaBuilder, Class<T> javaType) {
super( criteriaBuilder, javaType );
}
public void registerParameters(ParameterRegistry registry) {
// nothing 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

@ -28,6 +28,7 @@ import java.util.Collection;
import org.hibernate.ejb.criteria.ParameterRegistry;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaQueryCompiler;
import org.hibernate.ejb.criteria.path.PluralAttributePath;
/**
* Represents a "size of" expression in regards to a persistent collection; the implication is
@ -38,17 +39,17 @@ import org.hibernate.ejb.criteria.CriteriaQueryCompiler;
public class SizeOfCollectionExpression<C extends Collection>
extends ExpressionImpl<Integer>
implements Serializable {
private final CollectionExpression<C> collectionExpression;
private final PluralAttributePath<C> collectionPath;
public SizeOfCollectionExpression(
CriteriaBuilderImpl criteriaBuilder,
CollectionExpression<C> collectionExpression) {
PluralAttributePath<C> collectionPath) {
super( criteriaBuilder, Integer.class);
this.collectionExpression = collectionExpression;
this.collectionPath = collectionPath;
}
public CollectionExpression<C> getCollectionExpression() {
return collectionExpression;
public PluralAttributePath<C> getCollectionPath() {
return collectionPath;
}
public void registerParameters(ParameterRegistry registry) {
@ -56,7 +57,7 @@ public class SizeOfCollectionExpression<C extends Collection>
}
public String render(CriteriaQueryCompiler.RenderingContext renderingContext) {
return "size(" + getCollectionExpression().render( renderingContext ) + ")";
return "size(" + getCollectionPath().render( renderingContext ) + ")";
}
public String renderProjection(CriteriaQueryCompiler.RenderingContext renderingContext) {

View File

@ -1,10 +1,10 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
* third-party contributors as indicated by either @author tags or express
* copyright attribution statements applied by the authors. All
* third-party contributions are distributed under license by Red Hat Inc.
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
@ -21,64 +21,123 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.ejb.criteria;
package org.hibernate.ejb.criteria.path;
import java.io.Serializable;
import java.util.Set;
import java.util.Collection;
import java.util.Map;
import java.util.LinkedHashSet;
import java.util.Set;
import javax.persistence.criteria.CollectionJoin;
import javax.persistence.criteria.Fetch;
import javax.persistence.criteria.From;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.CollectionJoin;
import javax.persistence.criteria.SetJoin;
import javax.persistence.criteria.ListJoin;
import javax.persistence.criteria.MapJoin;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Fetch;
import javax.persistence.criteria.SetJoin;
import javax.persistence.metamodel.Attribute;
import javax.persistence.metamodel.Attribute.PersistentAttributeType;
import javax.persistence.metamodel.SingularAttribute;
import javax.persistence.metamodel.CollectionAttribute;
import javax.persistence.metamodel.SetAttribute;
import javax.persistence.metamodel.ListAttribute;
import javax.persistence.metamodel.MapAttribute;
import javax.persistence.metamodel.EntityType;
import javax.persistence.metamodel.ManagedType;
import javax.persistence.metamodel.MapAttribute;
import javax.persistence.metamodel.PluralAttribute;
import javax.persistence.metamodel.Bindable;
import javax.persistence.metamodel.SetAttribute;
import javax.persistence.metamodel.SingularAttribute;
import javax.persistence.metamodel.Type;
import javax.persistence.metamodel.PluralAttribute.CollectionType;
import javax.persistence.metamodel.Type.PersistenceType;
import org.hibernate.ejb.criteria.expression.CollectionExpression;
import org.hibernate.ejb.criteria.expression.EntityTypeExpression;
import org.hibernate.ejb.criteria.BasicPathUsageException;
import org.hibernate.ejb.criteria.CollectionJoinImplementor;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaQueryCompiler;
import org.hibernate.ejb.criteria.CriteriaSubqueryImpl;
import org.hibernate.ejb.criteria.FromImplementor;
import org.hibernate.ejb.criteria.JoinImplementor;
import org.hibernate.ejb.criteria.ListJoinImplementor;
import org.hibernate.ejb.criteria.MapJoinImplementor;
import org.hibernate.ejb.criteria.PathSource;
import org.hibernate.ejb.criteria.SetJoinImplementor;
/**
* TODO : javadoc
* Convenience base class for various {@link javax.persistence.criteria.From} implementors.
*
* @author Steve Ebersole
*/
public abstract class FromImpl<Z,X>
extends PathImpl<X>
implements From<Z,X>, TableExpressionMapper, Serializable {
public abstract class AbstractFromImpl<Z,X>
extends AbstractPathImpl<X>
implements From<Z,X>, FromImplementor<Z,X>, Serializable {
public static final JoinType DEFAULT_JOIN_TYPE = JoinType.INNER;
private final Expression<Class<? extends X>> typeExpression;
private Set<Join<X, ?>> joins;
private Set<Fetch<X, ?>> fetches;
/**
* Helper contract used to define who/what keeps track of joins and fetches made from this <tt>FROM</tt>.
*/
public static interface JoinScope<X> extends Serializable {
public void addJoin(Join<X, ?> join);
public void addFetch(Fetch<X,?> fetch);
public boolean isCorrelated();
public From<?, X> getCorrelationParent();
public AbstractFromImpl(CriteriaBuilderImpl criteriaBuilder, Class<X> javaType) {
this( criteriaBuilder, javaType, null );
}
public AbstractFromImpl(CriteriaBuilderImpl criteriaBuilder, Class<X> javaType, PathSource pathSource) {
super( criteriaBuilder, javaType, pathSource );
}
@Override
@SuppressWarnings({ "unchecked" })
public PathSource<Z> getPathSource() {
return super.getPathSource();
}
@Override
public String getPathIdentifier() {
return getAlias();
}
/**
* {@inheritDoc}
*/
@Override
protected boolean canBeDereferenced() {
return true;
}
/**
* {@inheritDoc}
*/
public void prepareAlias(CriteriaQueryCompiler.RenderingContext renderingContext) {
if ( getAlias() == null ) {
setAlias( renderingContext.generateAlias() );
}
}
/**
* {@inheritDoc}
*/
public Attribute<?, ?> getAttribute() {
return null;
}
/**
* {@inheritDoc}
*/
public From<?, Z> getParent() {
return null;
}
/**
* {@inheritDoc}
*/
@SuppressWarnings({ "unchecked" })
protected Attribute<X, ?> locateAttributeInternal(String name) {
return (Attribute<X, ?>) locateManagedType().getAttribute( name );
}
@SuppressWarnings({ "unchecked" })
protected ManagedType<? super X> locateManagedType() {
// by default, this should be the model
return (ManagedType<? super X>) getModel();
}
// CORRELATION ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
private From<Z,X> correlationParent;
private JoinScope<X> joinScope = new JoinScope<X>() {
public void addJoin(Join<X, ?> join) {
if ( joins == null ) {
@ -93,72 +152,50 @@ public abstract class FromImpl<Z,X>
}
fetches.add( fetch );
}
public boolean isCorrelated() {
return false;
}
public From<?, X> getCorrelationParent() {
return null;
}
};
/**
* Special constructor for {@link RootImpl}.
*
* @param criteriaBuilder The query build
* @param entityType The entity defining this root
* {@inheritDoc}
*/
@SuppressWarnings({ "unchecked" })
protected FromImpl(CriteriaBuilderImpl criteriaBuilder, EntityType<X> entityType) {
super( criteriaBuilder, entityType.getBindableJavaType(), null, null, entityType );
this.typeExpression = new EntityTypeExpression( criteriaBuilder, entityType.getBindableJavaType() );
public boolean isCorrelated() {
return getCorrelationParent() != null;
}
/**
* The general constructor for a {@link From} implementor.
*
* @param criteriaBuilder
* @param javaType
* @param origin
* @param attribute
* @param model
* {@inheritDoc}
*/
@SuppressWarnings({ "unchecked" })
public FromImpl(
CriteriaBuilderImpl criteriaBuilder,
Class<X> javaType,
PathImpl<Z> origin,
Attribute<? super Z, ?> attribute,
Bindable<X> model) {
super( criteriaBuilder, javaType, origin, attribute, model );
this.typeExpression = new EntityTypeExpression( criteriaBuilder, model.getBindableJavaType() );
public From<Z,X> getCorrelationParent() {
return correlationParent;
}
protected void defineJoinScope(JoinScope<X> joinScope) {
/**
* {@inheritDoc}
*/
@SuppressWarnings({ "unchecked" })
public FromImplementor<Z, X> correlateTo(CriteriaSubqueryImpl subquery) {
final FromImplementor<Z, X> correlationDelegate = createCorrelationDelegate();
correlationDelegate.prepareCorrelationDelegate( subquery.getJoinScope(), this );
return correlationDelegate;
}
protected abstract FromImplementor<Z, X> createCorrelationDelegate();
public void prepareCorrelationDelegate(JoinScope<X> joinScope, FromImplementor<Z, X> parent) {
this.joinScope = joinScope;
this.correlationParent = parent;
}
@Override
public Expression<Class<? extends X>> type() {
return typeExpression;
}
/**
* Get the attribute by name from the underlying model. This alows subclasses to
* define exactly how the attribute is derived.
*
* @param name The attribute name
*
* @return The attribute.
*
* @throws IllegalArgumentException If no such attribute is found (follows exception type from {@link ManagedType}).
*/
protected abstract Attribute<X,?> getAttribute(String name);
// JOINS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
protected abstract boolean canBeJoinSource();
private RuntimeException illegalJoin() {
return new IllegalArgumentException(
"Collection of values [" + getPathIdentifier() + "] cannot be source of a join"
);
}
/**
* {@inheritDoc}
*/
@ -177,13 +214,17 @@ public abstract class FromImpl<Z,X>
* {@inheritDoc}
*/
public <Y> Join<X, Y> join(SingularAttribute<? super X, Y> attribute, JoinType jt) {
if ( ! canBeJoinSource() ) {
throw illegalJoin();
}
Join<X, Y> join = constructJoin( attribute, jt );
joinScope.addJoin( join );
return join;
}
private <Y> JoinImplementors.JoinImplementor<X, Y> constructJoin(SingularAttribute<? super X, Y> attribute, JoinType jt) {
if ( PersistenceType.BASIC.equals( attribute.getType().getPersistenceType() ) ) {
private <Y> JoinImplementor<X, Y> constructJoin(SingularAttribute<? super X, Y> attribute, JoinType jt) {
if ( Type.PersistenceType.BASIC.equals( attribute.getType().getPersistenceType() ) ) {
throw new BasicPathUsageException( "Cannot join to attribute of basic type", attribute );
}
@ -194,7 +235,7 @@ public abstract class FromImpl<Z,X>
}
final Class<Y> attributeType = attribute.getBindableJavaType();
return new JoinImpl<X, Y>(
return new SingularAttributeJoin<X,Y>(
queryBuilder(),
attributeType,
this,
@ -213,41 +254,30 @@ public abstract class FromImpl<Z,X>
* {@inheritDoc}
*/
public <Y> CollectionJoin<X, Y> join(CollectionAttribute<? super X, Y> collection, JoinType jt) {
if ( ! canBeJoinSource() ) {
throw illegalJoin();
}
final CollectionJoin<X, Y> join = constructJoin( collection, jt );
joinScope.addJoin( join );
return join;
}
private <Y> JoinImplementors.CollectionJoinImplementor<X, Y> constructJoin(CollectionAttribute<? super X, Y> collection, JoinType jt) {
private <Y> CollectionJoinImplementor<X, Y> constructJoin(CollectionAttribute<? super X, Y> collection, JoinType jt) {
if ( jt.equals( JoinType.RIGHT ) ) {
throw new UnsupportedOperationException( "RIGHT JOIN not supported" );
}
final Class<Y> attributeType = collection.getBindableJavaType();
final JoinImplementors.CollectionJoinImplementor<X, Y> join;
if ( isBasicCollection( collection ) ) {
join = new BasicCollectionJoinImpl<X, Y>(
queryBuilder(),
attributeType,
this,
collection,
jt
);
}
else {
join = new CollectionJoinImpl<X, Y>(
queryBuilder(),
attributeType,
this,
collection,
jt
);
}
return join;
}
// TODO : runtime check that the attribute in fact belongs to this From's model/bindable
private boolean isBasicCollection(PluralAttribute collection) {
return PersistenceType.BASIC.equals( collection.getElementType().getPersistenceType() );
final Class<Y> attributeType = collection.getBindableJavaType();
return new CollectionAttributeJoin<X, Y>(
queryBuilder(),
attributeType,
this,
collection,
jt
);
}
/**
@ -261,25 +291,24 @@ public abstract class FromImpl<Z,X>
* {@inheritDoc}
*/
public <Y> SetJoin<X, Y> join(SetAttribute<? super X, Y> set, JoinType jt) {
if ( ! canBeJoinSource() ) {
throw illegalJoin();
}
final SetJoin<X, Y> join = constructJoin( set, jt );
joinScope.addJoin( join );
return join;
}
private <Y> JoinImplementors.SetJoinImplementor<X, Y> constructJoin(SetAttribute<? super X, Y> set, JoinType jt) {
private <Y> SetJoinImplementor<X, Y> constructJoin(SetAttribute<? super X, Y> set, JoinType jt) {
if ( jt.equals( JoinType.RIGHT ) ) {
throw new UnsupportedOperationException( "RIGHT JOIN not supported" );
}
// TODO : runtime check that the attribute in fact belongs to this From's model/bindable
final Class<Y> attributeType = set.getBindableJavaType();
final JoinImplementors.SetJoinImplementor<X, Y> join;
if ( isBasicCollection( set ) ) {
join = new BasicSetJoinImpl<X, Y>( queryBuilder(), attributeType, this, set, jt );
}
else {
join = new SetJoinImpl<X, Y>( queryBuilder(), attributeType, this, set, jt );
}
return join;
return new SetAttributeJoin<X,Y>( queryBuilder(), attributeType, this, set, jt );
}
/**
@ -293,25 +322,24 @@ public abstract class FromImpl<Z,X>
* {@inheritDoc}
*/
public <Y> ListJoin<X, Y> join(ListAttribute<? super X, Y> list, JoinType jt) {
if ( ! canBeJoinSource() ) {
throw illegalJoin();
}
final ListJoin<X, Y> join = constructJoin( list, jt );
joinScope.addJoin( join );
return join;
}
private <Y> JoinImplementors.ListJoinImplementor<X, Y> constructJoin(ListAttribute<? super X, Y> list, JoinType jt) {
private <Y> ListJoinImplementor<X, Y> constructJoin(ListAttribute<? super X, Y> list, JoinType jt) {
if ( jt.equals( JoinType.RIGHT ) ) {
throw new UnsupportedOperationException( "RIGHT JOIN not supported" );
}
// TODO : runtime check that the attribute in fact belongs to this From's model/bindable
final Class<Y> attributeType = list.getBindableJavaType();
final JoinImplementors.ListJoinImplementor<X, Y> join;
if ( isBasicCollection( list ) ) {
join = new BasicListJoinImpl<X, Y>( queryBuilder(), attributeType, this, list, jt );
}
else {
join = new ListJoinImpl<X, Y>( queryBuilder(), attributeType, this, list, jt );
}
return join;
return new ListAttributeJoin<X,Y>( queryBuilder(), attributeType, this, list, jt );
}
/**
@ -325,25 +353,24 @@ public abstract class FromImpl<Z,X>
* {@inheritDoc}
*/
public <K, V> MapJoin<X, K, V> join(MapAttribute<? super X, K, V> map, JoinType jt) {
if ( ! canBeJoinSource() ) {
throw illegalJoin();
}
final MapJoin<X, K, V> join = constructJoin( map, jt );
joinScope.addJoin( join );
return join;
}
private <K, V> JoinImplementors.MapJoinImplementor<X, K, V> constructJoin(MapAttribute<? super X, K, V> map, JoinType jt) {
private <K, V> MapJoinImplementor<X, K, V> constructJoin(MapAttribute<? super X, K, V> map, JoinType jt) {
if ( jt.equals( JoinType.RIGHT ) ) {
throw new UnsupportedOperationException( "RIGHT JOIN not supported" );
}
// TODO : runtime check that the attribute in fact belongs to this From's model/bindable
final Class<V> attributeType = map.getBindableJavaType();
final JoinImplementors.MapJoinImplementor<X, K, V> join;
if ( isBasicCollection( map ) ) {
join = new BasicMapJoinImpl<X,K,V>( queryBuilder(), attributeType, this, map, jt );
}
else {
join = new MapJoinImpl<X,K,V>( queryBuilder(), attributeType, this, map, jt );
}
return join;
return new MapAttributeJoin<X, K, V>( queryBuilder(), attributeType, this, map, jt );
}
/**
@ -358,20 +385,24 @@ public abstract class FromImpl<Z,X>
*/
@SuppressWarnings({ "unchecked" })
public <X,Y> Join<X, Y> join(String attributeName, JoinType jt) {
if ( ! canBeJoinSource() ) {
throw illegalJoin();
}
if ( jt.equals( JoinType.RIGHT ) ) {
throw new UnsupportedOperationException( "RIGHT JOIN not supported" );
}
final Attribute<X,?> attribute = (Attribute<X, ?>) getAttribute( attributeName );
final Attribute<X,?> attribute = (Attribute<X, ?>) locateAttribute( attributeName );
if ( attribute.isCollection() ) {
final PluralAttribute pluralAttribute = ( PluralAttribute ) attribute;
if ( CollectionType.COLLECTION.equals( pluralAttribute.getCollectionType() ) ) {
if ( PluralAttribute.CollectionType.COLLECTION.equals( pluralAttribute.getCollectionType() ) ) {
return (Join<X,Y>) join( (CollectionAttribute) attribute, jt );
}
else if ( CollectionType.LIST.equals( pluralAttribute.getCollectionType() ) ) {
else if ( PluralAttribute.CollectionType.LIST.equals( pluralAttribute.getCollectionType() ) ) {
return (Join<X,Y>) join( (ListAttribute) attribute, jt );
}
else if ( CollectionType.SET.equals( pluralAttribute.getCollectionType() ) ) {
else if ( PluralAttribute.CollectionType.SET.equals( pluralAttribute.getCollectionType() ) ) {
return (Join<X,Y>) join( (SetAttribute) attribute, jt );
}
else {
@ -395,13 +426,13 @@ public abstract class FromImpl<Z,X>
*/
@SuppressWarnings({ "unchecked" })
public <X,Y> CollectionJoin<X, Y> joinCollection(String attributeName, JoinType jt) {
final Attribute<X,?> attribute = (Attribute<X, ?>) getAttribute( attributeName );
final Attribute<X,?> attribute = (Attribute<X, ?>) locateAttribute( attributeName );
if ( ! attribute.isCollection() ) {
throw new IllegalArgumentException( "Requested attribute was not a collection" );
}
final PluralAttribute pluralAttribute = ( PluralAttribute ) attribute;
if ( ! CollectionType.COLLECTION.equals( pluralAttribute.getCollectionType() ) ) {
if ( ! PluralAttribute.CollectionType.COLLECTION.equals( pluralAttribute.getCollectionType() ) ) {
throw new IllegalArgumentException( "Requested attribute was not a collection" );
}
@ -420,13 +451,13 @@ public abstract class FromImpl<Z,X>
*/
@SuppressWarnings({ "unchecked" })
public <X,Y> SetJoin<X, Y> joinSet(String attributeName, JoinType jt) {
final Attribute<X,?> attribute = (Attribute<X, ?>) getAttribute( attributeName );
final Attribute<X,?> attribute = (Attribute<X, ?>) locateAttribute( attributeName );
if ( ! attribute.isCollection() ) {
throw new IllegalArgumentException( "Requested attribute was not a set" );
}
final PluralAttribute pluralAttribute = ( PluralAttribute ) attribute;
if ( ! CollectionType.SET.equals( pluralAttribute.getCollectionType() ) ) {
if ( ! PluralAttribute.CollectionType.SET.equals( pluralAttribute.getCollectionType() ) ) {
throw new IllegalArgumentException( "Requested attribute was not a set" );
}
@ -445,13 +476,13 @@ public abstract class FromImpl<Z,X>
*/
@SuppressWarnings({ "unchecked" })
public <X,Y> ListJoin<X, Y> joinList(String attributeName, JoinType jt) {
final Attribute<X,?> attribute = (Attribute<X, ?>) getAttribute( attributeName );
final Attribute<X,?> attribute = (Attribute<X, ?>) locateAttribute( attributeName );
if ( ! attribute.isCollection() ) {
throw new IllegalArgumentException( "Requested attribute was not a list" );
}
final PluralAttribute pluralAttribute = ( PluralAttribute ) attribute;
if ( ! CollectionType.LIST.equals( pluralAttribute.getCollectionType() ) ) {
if ( ! PluralAttribute.CollectionType.LIST.equals( pluralAttribute.getCollectionType() ) ) {
throw new IllegalArgumentException( "Requested attribute was not a list" );
}
@ -470,13 +501,13 @@ public abstract class FromImpl<Z,X>
*/
@SuppressWarnings({ "unchecked" })
public <X, K, V> MapJoin<X, K, V> joinMap(String attributeName, JoinType jt) {
final Attribute<X,?> attribute = (Attribute<X, ?>) getAttribute( attributeName );
final Attribute<X,?> attribute = (Attribute<X, ?>) locateAttribute( attributeName );
if ( ! attribute.isCollection() ) {
throw new IllegalArgumentException( "Requested attribute was not a map" );
}
final PluralAttribute pluralAttribute = ( PluralAttribute ) attribute;
if ( ! CollectionType.MAP.equals( pluralAttribute.getCollectionType() ) ) {
if ( ! PluralAttribute.CollectionType.MAP.equals( pluralAttribute.getCollectionType() ) ) {
throw new IllegalArgumentException( "Requested attribute was not a map" );
}
@ -486,6 +517,17 @@ public abstract class FromImpl<Z,X>
// FETCHES ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
protected boolean canBeFetchSource() {
// the conditions should be the same...
return canBeJoinSource();
}
private RuntimeException illegalFetch() {
return new IllegalArgumentException(
"Collection of values [" + getPathIdentifier() + "] cannot be source of a fetch"
);
}
/**
* {@inheritDoc}
*/
@ -493,21 +535,15 @@ public abstract class FromImpl<Z,X>
return fetches;
}
/**
* Retrieve the collection of fetches, imnplementing delayed creations. Calls on this method
* assume the set is physically needed, and as a result the set is built if not already.
*
* @return The set of fetches.
*/
public Set<Fetch<X, ?>> internalGetFetches() {
return fetches;
}
public <Y> Fetch<X, Y> fetch(SingularAttribute<? super X, Y> singularAttribute) {
return fetch( singularAttribute, DEFAULT_JOIN_TYPE );
}
public <Y> Fetch<X, Y> fetch(SingularAttribute<? super X, Y> attribute, JoinType jt) {
if ( ! canBeFetchSource() ) {
throw illegalFetch();
}
Fetch<X, Y> fetch = constructJoin( attribute, jt );
joinScope.addFetch( fetch );
return fetch;
@ -518,15 +554,19 @@ public abstract class FromImpl<Z,X>
}
public <Y> Fetch<X, Y> fetch(PluralAttribute<? super X, ?, Y> pluralAttribute, JoinType jt) {
if ( ! canBeFetchSource() ) {
throw illegalFetch();
}
final Fetch<X, Y> fetch;
// TODO : combine Fetch and Join hierarchies (JoinImplementor extends Join,Fetch???)
if ( CollectionType.COLLECTION.equals( pluralAttribute.getCollectionType() ) ) {
if ( PluralAttribute.CollectionType.COLLECTION.equals( pluralAttribute.getCollectionType() ) ) {
fetch = constructJoin( (CollectionAttribute<X,Y>) pluralAttribute, jt );
}
else if ( CollectionType.LIST.equals( pluralAttribute.getCollectionType() ) ) {
else if ( PluralAttribute.CollectionType.LIST.equals( pluralAttribute.getCollectionType() ) ) {
fetch = constructJoin( (ListAttribute<X,Y>) pluralAttribute, jt );
}
else if ( CollectionType.SET.equals( pluralAttribute.getCollectionType() ) ) {
else if ( PluralAttribute.CollectionType.SET.equals( pluralAttribute.getCollectionType() ) ) {
fetch = constructJoin( (SetAttribute<X,Y>) pluralAttribute, jt );
}
else {
@ -542,7 +582,11 @@ public abstract class FromImpl<Z,X>
@SuppressWarnings({ "unchecked" })
public <X,Y> Fetch<X, Y> fetch(String attributeName, JoinType jt) {
Attribute<X,?> attribute = (Attribute<X, ?>) getAttribute( attributeName );
if ( ! canBeFetchSource() ) {
throw illegalFetch();
}
Attribute<X,?> attribute = (Attribute<X, ?>) locateAttribute( attributeName );
if ( attribute.isCollection() ) {
return (Fetch<X, Y>) fetch( (PluralAttribute) attribute, jt );
}
@ -550,80 +594,4 @@ public abstract class FromImpl<Z,X>
return (Fetch<X, Y>) fetch( (SingularAttribute) attribute, jt );
}
}
// PATH HANDLING ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@Override
public <Y> Path<Y> get(SingularAttribute<? super X, Y> attribute) {
if ( PersistentAttributeType.BASIC.equals( attribute.getPersistentAttributeType() ) ) {
return new PathImpl<Y>( queryBuilder(), attribute.getJavaType(), this, attribute, attribute.getBindableType() );
}
else {
return join( attribute );
}
}
@Override
public <E, C extends Collection<E>> Expression<C> get(PluralAttribute<X, C, E> 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(), this, map );
}
@Override
@SuppressWarnings({ "unchecked" })
public <Y> Path<Y> get(String attributeName) {
Attribute attribute = getAttribute( attributeName );
if ( attribute.isCollection() ) {
final PluralAttribute<X,?,Y> pluralAttribute = (PluralAttribute<X, ?, Y>) attribute;
if ( CollectionType.COLLECTION.equals( pluralAttribute.getCollectionType() ) ) {
return join( (CollectionAttribute<X,Y>) attribute );
}
else if ( CollectionType.LIST.equals( pluralAttribute.getCollectionType() ) ) {
return join( (ListAttribute<X,Y>) attribute );
}
else if ( CollectionType.SET.equals( pluralAttribute.getCollectionType() ) ) {
return join( (SetAttribute<X,Y>) attribute );
}
else {
return join( (MapAttribute<X,?,Y>) attribute );
}
}
else {
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

@ -0,0 +1,103 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.ejb.criteria.path;
import java.io.Serializable;
import javax.persistence.criteria.From;
import javax.persistence.criteria.JoinType;
import javax.persistence.metamodel.Attribute;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaQueryCompiler;
import org.hibernate.ejb.criteria.CriteriaSubqueryImpl;
import org.hibernate.ejb.criteria.FromImplementor;
import org.hibernate.ejb.criteria.JoinImplementor;
import org.hibernate.ejb.criteria.PathSource;
/**
* TODO : javadoc
*
* @author Steve Ebersole
*/
public abstract class AbstractJoinImpl<Z, X>
extends AbstractFromImpl<Z, X>
implements JoinImplementor<Z,X>, Serializable {
private final Attribute<? super Z, ?> joinAttribute;
private final JoinType joinType;
public AbstractJoinImpl(
CriteriaBuilderImpl criteriaBuilder,
PathSource<Z> pathSource,
Attribute<? super Z, X> joinAttribute,
JoinType joinType) {
this( criteriaBuilder, joinAttribute.getJavaType(), pathSource, joinAttribute, joinType );
}
public AbstractJoinImpl(
CriteriaBuilderImpl criteriaBuilder,
Class<X> javaType,
PathSource<Z> pathSource,
Attribute<? super Z, ?> joinAttribute,
JoinType joinType) {
super( criteriaBuilder, javaType, pathSource );
this.joinAttribute = joinAttribute;
this.joinType = joinType;
}
/**
* {@inheritDoc}
*/
public Attribute<? super Z, ?> getAttribute() {
return joinAttribute;
}
/**
* {@inheritDoc}
*/
public JoinType getJoinType() {
return joinType;
}
/**
* {@inheritDoc}
*/
@SuppressWarnings({ "unchecked" })
public From<?, Z> getParent() {
// this cast should be ok by virtue of our constructors...
return (From<?, Z>) getPathSource();
}
public String renderTableExpression(CriteriaQueryCompiler.RenderingContext renderingContext) {
prepareAlias( renderingContext );
( (FromImplementor) getParent() ).prepareAlias( renderingContext );
return getParent().getAlias() + '.' + getAttribute().getName() + " as " + getAlias();
}
public JoinImplementor<Z, X> correlateTo(CriteriaSubqueryImpl subquery) {
return (JoinImplementor<Z, X>) super.correlateTo( subquery );
}
}

View File

@ -0,0 +1,263 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.ejb.criteria.path;
import java.io.Serializable;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Path;
import javax.persistence.metamodel.Attribute;
import javax.persistence.metamodel.MapAttribute;
import javax.persistence.metamodel.PluralAttribute;
import javax.persistence.metamodel.SingularAttribute;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaQueryCompiler;
import org.hibernate.ejb.criteria.ParameterRegistry;
import org.hibernate.ejb.criteria.PathImplementor;
import org.hibernate.ejb.criteria.PathSource;
import org.hibernate.ejb.criteria.expression.ExpressionImpl;
import org.hibernate.ejb.criteria.expression.PathTypeExpression;
/**
* Convenience base class for various {@link Path} implementors.
*
* @author Steve Ebersole
*/
public abstract class AbstractPathImpl<X>
extends ExpressionImpl<X>
implements Path<X>, PathImplementor<X>, Serializable {
private final PathSource pathSource;
private final Expression<Class<? extends X>> typeExpression;
private Map<String,Path> attributePathRegistry;
/**
* Constructs a basic path instance.
*
* @param criteriaBuilder The criteria builder
* @param javaType The java type of this path
* @param pathSource The source (or origin) from which this path originates
*/
@SuppressWarnings({ "unchecked" })
public AbstractPathImpl(
CriteriaBuilderImpl criteriaBuilder,
Class<X> javaType,
PathSource pathSource) {
super( criteriaBuilder, javaType );
this.pathSource = pathSource;
this.typeExpression = new PathTypeExpression( queryBuilder(), getJavaType() );
}
public PathSource getPathSource() {
return pathSource;
}
/**
* {@inheritDoc}
*/
public PathSource<?> getParentPath() {
return getPathSource();
}
/**
* {@inheritDoc}
*/
@SuppressWarnings({ "unchecked" })
public Expression<Class<? extends X>> type() {
return typeExpression;
}
/**
* {@inheritDoc}
*/
public String getPathIdentifier() {
return getPathSource().getPathIdentifier() + "." + getAttribute().getName();
}
protected abstract boolean canBeDereferenced();
protected final RuntimeException illegalDereference() {
return new IllegalArgumentException(
"Illegal attempt to dereference path source [" + getPathSource().getPathIdentifier() + "]"
);
}
protected final RuntimeException unknownAttribute(String attributeName) {
return new IllegalArgumentException(
"Unable to resolve attribute [" + attributeName + "] against path [" +
getPathSource().getPathIdentifier() + "]"
);
}
protected final Path resolveCachedAttributePath(String attributeName) {
return attributePathRegistry == null
? null
: attributePathRegistry.get( attributeName );
}
protected final void registerAttributePath(String attributeName, Path path) {
if ( attributePathRegistry == null ) {
attributePathRegistry = new HashMap<String,Path>();
}
attributePathRegistry.put( attributeName, path );
}
/**
* {@inheritDoc}
*/
@SuppressWarnings({ "unchecked" })
public <Y> Path<Y> get(SingularAttribute<? super X, Y> attribute) {
if ( ! canBeDereferenced() ) {
throw illegalDereference();
}
SingularAttributePath<Y> path = (SingularAttributePath<Y>) resolveCachedAttributePath( attribute.getName() );
if ( path == null ) {
path = new SingularAttributePath<Y>( queryBuilder(), attribute.getJavaType(), this, attribute );
registerAttributePath( attribute.getName(), path );
}
return path;
}
/**
* {@inheritDoc}
*/
@SuppressWarnings({ "unchecked" })
public <E, C extends Collection<E>> Expression<C> get(PluralAttribute<X, C, E> attribute) {
if ( ! canBeDereferenced() ) {
throw illegalDereference();
}
PluralAttributePath<C> path = (PluralAttributePath<C>) resolveCachedAttributePath( attribute.getName() );
if ( path == null ) {
path = new PluralAttributePath<C>( queryBuilder(), this, attribute );
registerAttributePath( attribute.getName(), path );
}
return path;
}
/**
* {@inheritDoc}
*/
@SuppressWarnings({ "unchecked" })
public <K, V, M extends Map<K, V>> Expression<M> get(MapAttribute<X, K, V> attribute) {
if ( ! canBeDereferenced() ) {
throw illegalDereference();
}
PluralAttributePath path = (PluralAttributePath) resolveCachedAttributePath( attribute.getName() );
if ( path == null ) {
path = new PluralAttributePath( queryBuilder(), this, attribute );
registerAttributePath( attribute.getName(), path );
}
return path;
}
/**
* {@inheritDoc}
*/
@SuppressWarnings({ "unchecked" })
public <Y> Path<Y> get(String attributeName) {
if ( ! canBeDereferenced() ) {
throw illegalDereference();
}
final Attribute attribute = locateAttribute( attributeName );
if ( attribute.isCollection() ) {
final PluralAttribute<X,Y,?> pluralAttribute = (PluralAttribute<X,Y,?>) attribute;
if ( PluralAttribute.CollectionType.MAP.equals( pluralAttribute.getCollectionType() ) ) {
return (PluralAttributePath<Y>) get( (MapAttribute<X,?,?>) pluralAttribute );
}
else {
return (PluralAttributePath<Y>) get( (PluralAttribute) pluralAttribute );
}
}
else {
return get( (SingularAttribute<X,Y>) attribute );
}
}
/**
* Get the attribute by name from the underlying model. This allows subclasses to
* define exactly how the attribute is derived.
*
* @param attributeName The name of the attribute to locate
*
* @return The attribute; should never return null.
*
* @throws IllegalArgumentException If no such attribute exists
*/
protected final Attribute locateAttribute(String attributeName) {
final Attribute attribute = locateAttributeInternal( attributeName );
if ( attribute == null ) {
throw unknownAttribute( attributeName );
}
return attribute;
}
/**
* Get the attribute by name from the underlying model. This allows subclasses to
* define exactly how the attribute is derived. Called from {@link #locateAttribute}
* which also applies nullness checking for proper error reporting.
*
* @param attributeName The name of the attribute to locate
*
* @return The attribute; may be null.
*
* @throws IllegalArgumentException If no such attribute exists
*/
protected abstract Attribute locateAttributeInternal(String attributeName);
/**
* {@inheritDoc}
*/
public void registerParameters(ParameterRegistry registry) {
// none to register
}
public void prepareAlias(CriteriaQueryCompiler.RenderingContext renderingContext) {
// Make sure we delegate up to our source (eventually up to the path root) to
// prepare the path properly.
getPathSource().prepareAlias( renderingContext );
}
/**
* {@inheritDoc}
*/
public String render(CriteriaQueryCompiler.RenderingContext renderingContext) {
getPathSource().prepareAlias( renderingContext );
return getPathSource().getPathIdentifier() + "." + getAttribute().getName();
}
/**
* {@inheritDoc}
*/
public String renderProjection(CriteriaQueryCompiler.RenderingContext renderingContext) {
return render( renderingContext );
}
}

View File

@ -0,0 +1,80 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.ejb.criteria.path;
import java.io.Serializable;
import java.util.Collection;
import javax.persistence.criteria.JoinType;
import javax.persistence.metamodel.CollectionAttribute;
import org.hibernate.ejb.criteria.CollectionJoinImplementor;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaSubqueryImpl;
import org.hibernate.ejb.criteria.FromImplementor;
import org.hibernate.ejb.criteria.PathImplementor;
import org.hibernate.ejb.criteria.PathSource;
/**
* TODO : javadoc
*
* @author Steve Ebersole
*/
public class CollectionAttributeJoin<O,E>
extends PluralAttributeJoinSupport<O,Collection<E>,E>
implements CollectionJoinImplementor<O,E>, Serializable {
public CollectionAttributeJoin(
CriteriaBuilderImpl criteriaBuilder,
Class<E> javaType,
PathSource<O> pathSource,
CollectionAttribute<? super O, E> joinAttribute,
JoinType joinType) {
super( criteriaBuilder, javaType, pathSource, joinAttribute, joinType );
}
public final CollectionAttributeJoin<O,E> correlateTo(CriteriaSubqueryImpl subquery) {
return (CollectionAttributeJoin<O,E>) super.correlateTo( subquery );
}
@Override
public CollectionAttribute<? super O, E> getAttribute() {
return (CollectionAttribute<? super O, E>) super.getAttribute();
}
@Override
public CollectionAttribute<? super O, E> getModel() {
return getAttribute();
}
@Override
protected FromImplementor<O, E> createCorrelationDelegate() {
return new CollectionAttributeJoin<O,E>(
queryBuilder(),
getJavaType(),
(PathImplementor<O>) getParentPath(),
getAttribute(),
getJoinType()
);
}
}

View File

@ -1,10 +1,10 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
* third-party contributors as indicated by either @author tags or express
* copyright attribution statements applied by the authors. All
* third-party contributions are distributed under license by Red Hat Inc.
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
@ -21,33 +21,46 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.ejb.criteria;
package org.hibernate.ejb.criteria.path;
import java.io.Serializable;
import java.util.List;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.From;
import javax.persistence.metamodel.ListAttribute;
import org.hibernate.ejb.criteria.JoinImplementors.ListJoinImplementor;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaSubqueryImpl;
import org.hibernate.ejb.criteria.FromImplementor;
import org.hibernate.ejb.criteria.ListJoinImplementor;
import org.hibernate.ejb.criteria.PathImplementor;
import org.hibernate.ejb.criteria.PathSource;
import org.hibernate.ejb.criteria.expression.ListIndexExpression;
/**
* Represents a join to a persistent collection, defined as type {@link java.util.List}, whose elements
* are basic type.
* TODO : javadoc
*
* @author Steve Ebersole
*/
public class BasicListJoinImpl<O,E>
extends AbstractBasicPluralJoin<O,java.util.List<E>,E>
implements JoinImplementors.ListJoinImplementor<O,E>, Serializable {
public class ListAttributeJoin<O,E>
extends PluralAttributeJoinSupport<O, List<E>,E>
implements ListJoinImplementor<O,E>, Serializable {
public BasicListJoinImpl(
public ListAttributeJoin(
CriteriaBuilderImpl criteriaBuilder,
Class<E> javaType,
PathImpl<O> lhs,
ListAttribute<? super O, ?> joinProperty,
PathSource<O> pathSource,
ListAttribute<? super O, E> joinAttribute,
JoinType joinType) {
super( criteriaBuilder, javaType, lhs, joinProperty, joinType);
super( criteriaBuilder, javaType, pathSource, joinAttribute, joinType );
}
/**
* {@inheritDoc}
*/
public Expression<Integer> index() {
return new ListIndexExpression( queryBuilder(), this, getAttribute() );
}
@Override
@ -60,37 +73,19 @@ public class BasicListJoinImpl<O,E>
return getAttribute();
}
public Expression<Integer> index() {
return new ListIndexExpression( queryBuilder(), this, getAttribute() );
@Override
public final ListAttributeJoin<O,E> correlateTo(CriteriaSubqueryImpl subquery) {
return (ListAttributeJoin<O,E>) super.correlateTo( subquery );
}
@Override
public ListJoinImplementor<O, E> correlateTo(CriteriaSubqueryImpl subquery) {
BasicListJoinImpl<O,E> correlation = new BasicListJoinImpl<O,E>(
protected FromImplementor<O, E> createCorrelationDelegate() {
return new ListAttributeJoin<O,E>(
queryBuilder(),
getJavaType(),
(PathImpl<O>) getParentPath(),
(PathImplementor<O>) getParentPath(),
getAttribute(),
getJoinType()
);
correlation.defineJoinScope( subquery.getJoinScope() );
correlation.correlationParent = this;
return correlation;
}
private From<O, E> correlationParent;
/**
* {@inheritDoc}
*/
public boolean isCorrelated() {
return getCorrelationParent() != null;
}
/**
* {@inheritDoc}
*/
public From<O, E> getCorrelationParent() {
return correlationParent;
}
}

View File

@ -0,0 +1,117 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.ejb.criteria.path;
import java.io.Serializable;
import java.util.Map;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.Path;
import javax.persistence.metamodel.MapAttribute;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaSubqueryImpl;
import org.hibernate.ejb.criteria.FromImplementor;
import org.hibernate.ejb.criteria.MapJoinImplementor;
import org.hibernate.ejb.criteria.PathImplementor;
import org.hibernate.ejb.criteria.PathSource;
import org.hibernate.ejb.criteria.expression.MapEntryExpression;
/**
* TODO : javadoc
*
* @author Steve Ebersole
*/
public class MapAttributeJoin<O,K,V>
extends PluralAttributeJoinSupport<O, Map<K,V>, V>
implements MapJoinImplementor<O,K,V>, Serializable {
public MapAttributeJoin(
CriteriaBuilderImpl criteriaBuilder,
Class<V> javaType,
PathSource<O> pathSource,
MapAttribute<? super O, K, V> joinAttribute,
JoinType joinType) {
super( criteriaBuilder, javaType, pathSource, joinAttribute, joinType );
}
@Override
public MapAttribute<? super O, K, V> getAttribute() {
return (MapAttribute<? super O, K, V>) super.getAttribute();
}
@Override
public MapAttribute<? super O, K, V> getModel() {
return getAttribute();
}
@Override
public final MapAttributeJoin<O,K,V> correlateTo(CriteriaSubqueryImpl subquery) {
return (MapAttributeJoin<O,K,V>) super.correlateTo( subquery );
}
@Override
protected FromImplementor<O, V> createCorrelationDelegate() {
return new MapAttributeJoin<O,K,V>(
queryBuilder(),
getJavaType(),
(PathImplementor<O>) getParentPath(),
getAttribute(),
getJoinType()
);
}
/**
* {@inheritDoc}
*/
public Path<V> value() {
return this;
}
/**
* {@inheritDoc}
*/
@SuppressWarnings({ "unchecked" })
public Expression<Map.Entry<K, V>> entry() {
return new MapEntryExpression( queryBuilder(), Map.Entry.class, this, getAttribute() );
}
/**
* {@inheritDoc}
*/
@SuppressWarnings({ "unchecked" })
public Path<K> key() {
final MapKeyHelpers.MapKeySource<K,V> mapKeySource = new MapKeyHelpers.MapKeySource<K,V>(
queryBuilder(),
getAttribute().getJavaType(),
this,
getAttribute()
);
final MapKeyHelpers.MapKeyAttribute mapKeyAttribute = new MapKeyHelpers.MapKeyAttribute( queryBuilder(), getAttribute() );
return new MapKeyHelpers.MapKeyPath( queryBuilder(), mapKeySource, mapKeyAttribute );
}
}

View File

@ -21,144 +21,167 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.ejb.criteria;
package org.hibernate.ejb.criteria.path;
import java.io.Serializable;
import java.lang.reflect.Member;
import java.util.Map;
import java.util.Map.Entry;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.From;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.MapJoin;
import javax.persistence.criteria.Path;
import javax.persistence.metamodel.Attribute;
import javax.persistence.metamodel.Bindable;
import javax.persistence.metamodel.ManagedType;
import javax.persistence.metamodel.MapAttribute;
import javax.persistence.metamodel.SingularAttribute;
import javax.persistence.metamodel.Type.PersistenceType;
import javax.persistence.metamodel.Type;
import org.hibernate.ejb.criteria.JoinImplementors.JoinImplementor;
import org.hibernate.ejb.criteria.expression.ExpressionImpl;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
import org.hibernate.ejb.criteria.MapJoinImplementor;
import org.hibernate.ejb.criteria.PathImplementor;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.type.Type;
/**
* {@link MapJoin} defines a number of methods which require {@link Path}, {@link Join} and {@link Attribute}
* implementations which do not fit nicely into the generic signatures it defines for everything else (mainly
* in terms of dealing with the map key). The implementations found here provide that bridge.
* {@link MapJoin#key} poses a number of implementation difficulties in terms of the type signatures
* amongst the {@link Path}, {@link Join} and {@link Attribute} reference at play. The implementations found here
* provide that bridge.
*
* @author Steve Ebersole
*/
public class MapKeyHelpers {
/**
* Represents a join to the key of a map attribute. Obviously the map key must be an
* entity or component type.
*
* @param <K> The type of the map key
* @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>, Serializable {
public MapKeyJoin(
CriteriaBuilderImpl criteriaBuilder,
MapPath<K,V> source,
MapKeyAttribute<K> attribute,
JoinType jt) {
super(
criteriaBuilder,
attribute.getJavaType(),
source,
attribute,
jt
);
}
@Override
public JoinImplementor<Map<K, V>, K> correlateTo(CriteriaSubqueryImpl subquery) {
throw new UnsupportedOperationException( "Map key join cannot be used as a correlation" );
}
public boolean isCorrelated() {
return false;
}
public From<Map<K, V>, K> getCorrelationParent() {
return null;
}
}
/**
* Models a path to a map key.
* Models a path to a map key. This is the actual return used from {@link MapJoin#key}
*
* @param <K> The type of the map key.
*/
public static class MapKeyPath<K> extends PathImpl<K> implements Path<K>, Serializable {
public static class MapKeyPath<K>
extends AbstractPathImpl<K>
implements PathImplementor<K>, Serializable {
private final MapKeyAttribute<K> mapKeyAttribute;
public MapKeyPath(
CriteriaBuilderImpl criteriaBuilder,
MapPath<K,?> source,
MapKeyAttribute<K> attribute) {
super( criteriaBuilder, attribute.getJavaType(), source, attribute, attribute.getType() );
MapKeySource<K,?> source,
MapKeyAttribute<K> mapKeyAttribute) {
super( criteriaBuilder, mapKeyAttribute.getJavaType(), source );
this.mapKeyAttribute = mapKeyAttribute;
}
@Override
public MapKeySource getPathSource() {
return (MapKeySource) super.getPathSource();
}
public MapKeyAttribute<K> getAttribute() {
return mapKeyAttribute;
}
private boolean isBasicTypeKey() {
return Attribute.PersistentAttributeType.BASIC ==
mapKeyAttribute.getPersistentAttributeType();
}
@Override
protected boolean canBeDereferenced() {
return ! isBasicTypeKey();
}
@Override
protected Attribute locateAttributeInternal(String attributeName) {
if ( ! canBeDereferenced() ) {
throw new IllegalArgumentException(
"Map key [" + getPathSource().getPathIdentifier() + "] cannot be dereferenced"
);
}
throw new UnsupportedOperationException( "Not yet supported!" );
}
public Bindable<K> getModel() {
return mapKeyAttribute;
}
}
/**
* Defines a {@link Path} resulting in a map attribute. This can then be used as the
* parent/origin/source for referencing the map-key.
* Defines a {@link Path} for the map which can then be used to represent the source of the
* map key "attribute".
*
* @param <K> The map key type
* @param <V> The map value type
*/
public static class MapPath<K,V> extends PathImpl<Map<K, V>> implements Path<Map<K, V>>, Serializable {
private final MapJoin<?,K,V> mapJoin;
public static class MapKeySource<K,V>
extends AbstractPathImpl<Map<K, V>>
implements PathImplementor<Map<K, V>>, Serializable {
public MapPath(
private final MapAttribute<?,K,V> mapAttribute;
private final MapJoinImplementor<?,K,V> mapJoin;
public MapKeySource(
CriteriaBuilderImpl criteriaBuilder,
Class<Map<K, V>> javaType,
MapJoin<?,K,V> mapJoin,
MapAttribute<?,K,V> attribute,
Object model) {
super( criteriaBuilder, javaType, null, attribute, model);
MapJoinImplementor<?,K,V> mapJoin,
MapAttribute<?,K,V> attribute) {
super( criteriaBuilder, javaType, null );
this.mapJoin = mapJoin;
this.mapAttribute = attribute;
}
@Override
public MapAttribute<?,K,V> getAttribute() {
return (MapAttribute<?,K,V>) super.getAttribute();
return mapAttribute;
}
@SuppressWarnings({ "unchecked" })
public Bindable<Map<K, V>> getModel() {
// TODO : ok??? the attribute is in fact bindable, but its type signature is different
return (Bindable<Map<K, V>>) mapAttribute;
}
@Override
public PathImpl<?> getParentPath() {
return (PathImpl<?>) mapJoin;
public PathImplementor<?> getParentPath() {
return (PathImplementor<?>) mapJoin.getParentPath();
}
@Override
protected boolean canBeDereferenced() {
return false;
}
@Override
protected Attribute locateAttributeInternal(String attributeName) {
throw new IllegalArgumentException( "Map [" + mapJoin.getPathIdentifier() + "] cannot be dereferenced" );
}
}
/**
* Defines an {@link Attribute} modelling of a map-key.
* <p/>
* TODO : Ideally something like this needs to be part of the metamodel package
* Disallow instantiation
*/
private MapKeyHelpers() {
}
/**
* Defines an {@link javax.persistence.metamodel.Attribute} modelling of a map-key.
*
* @param <K> The type of the map key
*/
public static class MapKeyAttribute<K> implements SingularAttribute<Map<K,?>,K>, Serializable {
public static class MapKeyAttribute<K>
implements SingularAttribute<Map<K,?>,K>, Bindable<K>, Serializable {
private final MapAttribute<?,K,?> attribute;
private final CollectionPersister mapPersister;
private final Type mapKeyType;
private final javax.persistence.metamodel.Type<K> jpaType;
private final org.hibernate.type.Type mapKeyType;
private final Type<K> jpaType;
private final BindableType jpaBindableType;
private final Class<K> jpaBinableJavaType;
private final PersistentAttributeType persistentAttributeType;
public MapKeyAttribute(CriteriaBuilderImpl criteriaBuilder, MapAttribute<?, K, ?> attribute) {
this.attribute = attribute;
this.jpaType = attribute.getKeyType();
this.jpaBinableJavaType = attribute.getKeyJavaType();
this.jpaBindableType = PersistenceType.ENTITY.equals( jpaType.getPersistenceType() )
this.jpaBindableType = Type.PersistenceType
.ENTITY.equals( jpaType.getPersistenceType() )
? BindableType.ENTITY_TYPE
: BindableType.SINGULAR_ATTRIBUTE;
@ -173,6 +196,12 @@ public class MapKeyHelpers {
if ( mapKeyType == null ) {
throw new IllegalStateException( "Could not determine map-key type [" + guessedRoleName + "]" );
}
this.persistentAttributeType = mapKeyType.isEntityType()
? PersistentAttributeType.MANY_TO_ONE
: mapKeyType.isComponentType()
? PersistentAttributeType.EMBEDDED
: PersistentAttributeType.BASIC;
}
private String determineRole(MapAttribute<?,K,?> attribute) {
@ -192,15 +221,7 @@ public class MapKeyHelpers {
* {@inheritDoc}
*/
public PersistentAttributeType getPersistentAttributeType() {
if ( mapKeyType.isEntityType() ) {
return PersistentAttributeType.MANY_TO_ONE;
}
else if ( mapKeyType.isComponentType() ) {
return PersistentAttributeType.EMBEDDED;
}
else {
return PersistentAttributeType.BASIC;
}
return persistentAttributeType;
}
/**
@ -252,7 +273,7 @@ public class MapKeyHelpers {
return false;
}
public javax.persistence.metamodel.Type<K> getType() {
public Type<K> getType() {
return jpaType;
}
@ -264,51 +285,4 @@ public class MapKeyHelpers {
return jpaBinableJavaType;
}
}
public static class MapEntryExpression<K,V>
extends ExpressionImpl<Map.Entry<K,V>>
implements Expression<Map.Entry<K,V>>, Serializable {
private final PathImpl origin;
private final MapAttribute<?, K, V> attribute;
public MapEntryExpression(
CriteriaBuilderImpl criteriaBuilder,
Class<Entry<K, V>> javaType,
PathImpl origin,
MapAttribute<?, K, V> attribute) {
super( criteriaBuilder, javaType);
this.origin = origin;
this.attribute = attribute;
}
public MapAttribute<?, K, V> getAttribute() {
return attribute;
}
public void registerParameters(ParameterRegistry registry) {
// none to register
}
public String render(CriteriaQueryCompiler.RenderingContext renderingContext) {
// i don't think this is valid 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()
+ '.'
+ ( (Renderable) getAttribute() ).renderProjection( renderingContext );
}
}
/**
* Disallow instantiation
*/
private MapKeyHelpers() {
}
}

View File

@ -0,0 +1,86 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.ejb.criteria.path;
import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.PluralJoin;
import javax.persistence.metamodel.Attribute;
import javax.persistence.metamodel.Bindable;
import javax.persistence.metamodel.ManagedType;
import javax.persistence.metamodel.PluralAttribute;
import javax.persistence.metamodel.Type;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
import org.hibernate.ejb.criteria.PathSource;
/**
* Support for defining joins to plural attributes (JPA requires typing based on
* the specific collection type so we cannot really implement all support in a
* single class)
*
* @author Steve Ebersole
*/
public abstract class PluralAttributeJoinSupport<O,C,E>
extends AbstractJoinImpl<O,E>
implements PluralJoin<O,C,E> {
public PluralAttributeJoinSupport(
CriteriaBuilderImpl criteriaBuilder,
Class<E> javaType,
PathSource<O> pathSource,
Attribute<? super O,?> joinAttribute,
JoinType joinType) {
super( criteriaBuilder, javaType, pathSource, joinAttribute, joinType );
}
@Override
public PluralAttribute<? super O, C, E> getAttribute() {
return (PluralAttribute<? super O, C, E>) super.getAttribute();
}
public PluralAttribute<? super O, C, E> getModel() {
return getAttribute();
}
@Override
protected ManagedType<E> locateManagedType() {
return isBasicCollection()
? null
: (ManagedType<E>) getAttribute().getElementType();
}
public boolean isBasicCollection() {
return Type.PersistenceType.BASIC.equals( getAttribute().getElementType().getPersistenceType() );
}
@Override
protected boolean canBeDereferenced() {
return !isBasicCollection();
}
@Override
protected boolean canBeJoinSource() {
return !isBasicCollection();
}
}

View File

@ -1,10 +1,10 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
* third-party contributors as indicated by either @author tags or express
* copyright attribution statements applied by the authors. All
* third-party contributions are distributed under license by Red Hat Inc.
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
@ -21,33 +21,35 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.ejb.criteria.expression;
package org.hibernate.ejb.criteria.path;
import java.io.Serializable;
import javax.persistence.metamodel.Attribute;
import javax.persistence.metamodel.Bindable;
import javax.persistence.metamodel.PluralAttribute;
import org.hibernate.ejb.criteria.ParameterRegistry;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
import org.hibernate.ejb.criteria.PathImpl;
import org.hibernate.ejb.criteria.CriteriaQueryCompiler;
import org.hibernate.ejb.criteria.PathSource;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.persister.collection.CollectionPersister;
/**
* TODO : javadoc
* Models a path for a {@link PluralAttribute} generally obtained from a
* {@link javax.persistence.criteria.Path#get} call
*
* @author Steve Ebersole
*/
public class CollectionExpression<C> extends ExpressionImpl<C> implements Serializable {
private final PathImpl origin;
public class PluralAttributePath<X> extends AbstractPathImpl<X> implements Serializable {
private final PluralAttribute<?,X,?> attribute;
private final CollectionPersister persister;
private final PluralAttribute<?, C, ?> attribute;
public CollectionExpression(
public PluralAttributePath(
CriteriaBuilderImpl criteriaBuilder,
Class<C> javaType,
PathImpl origin,
PluralAttribute<?, C, ?> attribute) {
this( criteriaBuilder, javaType, resolvePersister( criteriaBuilder, attribute ), origin, attribute );
PathSource source,
PluralAttribute<?,X,?> attribute) {
super( criteriaBuilder, attribute.getJavaType(), source );
this.attribute = attribute;
this.persister = resolvePersister( criteriaBuilder, attribute );
}
private static CollectionPersister resolvePersister(CriteriaBuilderImpl criteriaBuilder, PluralAttribute attribute) {
@ -61,35 +63,32 @@ public class CollectionExpression<C> extends ExpressionImpl<C> implements Serial
'.' + attribute.getName();
}
public CollectionExpression(
CriteriaBuilderImpl criteriaBuilder,
Class<C> javaType,
CollectionPersister persister,
PathImpl origin,
PluralAttribute<?, C, ?> attribute) {
super( criteriaBuilder, javaType );
this.origin = origin;
this.persister = persister;
this.attribute = attribute;
}
public PluralAttribute<?, C, ?> getAttribute() {
public PluralAttribute<?,X,?> getAttribute() {
return attribute;
}
@SuppressWarnings({ "UnusedDeclaration" })
public CollectionPersister getPersister() {
return persister;
}
public void registerParameters(ParameterRegistry registry) {
// none to register
@Override
protected boolean canBeDereferenced() {
// cannot be dereferenced
return false;
}
public String render(CriteriaQueryCompiler.RenderingContext renderingContext) {
return origin.getPathIdentifier() + '.' + getAttribute().getName();
@Override
protected Attribute locateAttributeInternal(String attributeName) {
throw new IllegalArgumentException( "Plural attribute paths cannot be further dereferenced" );
}
public String renderProjection(CriteriaQueryCompiler.RenderingContext renderingContext) {
return render( renderingContext );
public Bindable<X> getModel() {
// the issue here is the parameterized type; X is the collection
// type (Map, Set, etc) while the "bindable" for a collection is the
// elements.
//
// TODO : throw exception instead?
return null;
}
}

View File

@ -0,0 +1,93 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.ejb.criteria.path;
import java.io.Serializable;
import javax.persistence.criteria.Root;
import javax.persistence.metamodel.EntityType;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaQueryCompiler;
import org.hibernate.ejb.criteria.CriteriaSubqueryImpl;
import org.hibernate.ejb.criteria.FromImplementor;
/**
* TODO : javadoc
*
* @author Steve Ebersole
*/
public class RootImpl<X> extends AbstractFromImpl<X,X> implements Root<X>, Serializable {
private final EntityType<X> entityType;
public RootImpl(
CriteriaBuilderImpl criteriaBuilder,
EntityType<X> entityType) {
super( criteriaBuilder, entityType.getJavaType() );
this.entityType = entityType;
}
public EntityType<X> getEntityType() {
return entityType;
}
public EntityType<X> getModel() {
return getEntityType();
}
@Override
protected FromImplementor<X, X> createCorrelationDelegate() {
return new RootImpl<X>( queryBuilder(), getEntityType() );
}
@Override
public RootImpl<X> correlateTo(CriteriaSubqueryImpl subquery) {
return (RootImpl<X>) super.correlateTo( subquery );
}
@Override
protected boolean canBeJoinSource() {
return true;
}
public String renderTableExpression(CriteriaQueryCompiler.RenderingContext renderingContext) {
prepareAlias( renderingContext );
return getModel().getName() + " as " + getAlias();
}
@Override
public String getPathIdentifier() {
return getAlias();
}
@Override
public String render(CriteriaQueryCompiler.RenderingContext renderingContext) {
prepareAlias( renderingContext );
return getAlias();
}
@Override
public String renderProjection(CriteriaQueryCompiler.RenderingContext renderingContext) {
return render( renderingContext );
}
}

View File

@ -0,0 +1,82 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.ejb.criteria.path;
import java.io.Serializable;
import java.util.Set;
import javax.persistence.criteria.JoinType;
import javax.persistence.metamodel.SetAttribute;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaSubqueryImpl;
import org.hibernate.ejb.criteria.FromImplementor;
import org.hibernate.ejb.criteria.PathImplementor;
import org.hibernate.ejb.criteria.PathSource;
import org.hibernate.ejb.criteria.SetJoinImplementor;
/**
* TODO : javadoc
*
* @author Steve Ebersole
*/
public class SetAttributeJoin<O,E>
extends PluralAttributeJoinSupport<O, Set<E>,E>
implements SetJoinImplementor<O,E>, Serializable {
public SetAttributeJoin(
CriteriaBuilderImpl criteriaBuilder,
Class<E> javaType,
PathSource<O> pathSource,
SetAttribute<? super O, E> joinAttribute,
JoinType joinType) {
super( criteriaBuilder, javaType, pathSource, joinAttribute, joinType );
}
@Override
public SetAttribute<? super O, E> getAttribute() {
return (SetAttribute<? super O, E>) super.getAttribute();
}
@Override
public SetAttribute<? super O, E> getModel() {
return getAttribute();
}
@Override
public final SetAttributeJoin<O,E> correlateTo(CriteriaSubqueryImpl subquery) {
return (SetAttributeJoin<O,E>) super.correlateTo( subquery );
}
@Override
protected FromImplementor<O, E> createCorrelationDelegate() {
return new SetAttributeJoin<O,E>(
queryBuilder(),
getJavaType(),
(PathImplementor<O>) getParentPath(),
getAttribute(),
getJoinType()
);
}
}

View File

@ -0,0 +1,88 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.ejb.criteria.path;
import javax.persistence.criteria.JoinType;
import javax.persistence.metamodel.Attribute;
import javax.persistence.metamodel.Bindable;
import javax.persistence.metamodel.SingularAttribute;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaSubqueryImpl;
import org.hibernate.ejb.criteria.FromImplementor;
import org.hibernate.ejb.criteria.PathSource;
/**
* TODO : javadoc
*
* @author Steve Ebersole
*/
public class SingularAttributeJoin<Z,X> extends AbstractJoinImpl<Z,X> {
private final Bindable<X> model;
@SuppressWarnings({ "unchecked" })
public SingularAttributeJoin(
CriteriaBuilderImpl criteriaBuilder,
Class<X> javaType,
PathSource<Z> pathSource,
SingularAttribute<? super Z, ?> joinAttribute,
JoinType joinType) {
super( criteriaBuilder, javaType, pathSource, joinAttribute, joinType );
this.model = (Bindable<X>) (
Attribute.PersistentAttributeType.EMBEDDED == joinAttribute.getPersistentAttributeType()
? joinAttribute
: criteriaBuilder.getEntityManagerFactory().getMetamodel().managedType( javaType )
);
}
@Override
public SingularAttribute<? super Z, ?> getAttribute() {
return (SingularAttribute<? super Z, ?>) super.getAttribute();
}
@Override
public SingularAttributeJoin<Z, X> correlateTo(CriteriaSubqueryImpl subquery) {
return (SingularAttributeJoin<Z, X>) super.correlateTo( subquery );
}
@Override
protected FromImplementor<Z, X> createCorrelationDelegate() {
return new SingularAttributeJoin<Z,X>(
queryBuilder(),
getJavaType(),
getPathSource(),
getAttribute(),
getJoinType()
);
}
@Override
protected boolean canBeJoinSource() {
return true;
}
public Bindable<X> getModel() {
return model;
}
}

View File

@ -0,0 +1,105 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.ejb.criteria.path;
import java.io.Serializable;
import javax.persistence.metamodel.Attribute;
import javax.persistence.metamodel.Bindable;
import javax.persistence.metamodel.EmbeddableType;
import javax.persistence.metamodel.IdentifiableType;
import javax.persistence.metamodel.ManagedType;
import javax.persistence.metamodel.SingularAttribute;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
import org.hibernate.ejb.criteria.PathSource;
/**
* Models a path for a {@link SingularAttribute} generally obtained from a
* {@link javax.persistence.criteria.Path#get(SingularAttribute)} call
*
* @author Steve Ebersole
*/
public class SingularAttributePath<X> extends AbstractPathImpl<X> implements Serializable {
private final SingularAttribute<?,X> attribute;
private final ManagedType<X> managedType;
@SuppressWarnings({ "unchecked" })
public SingularAttributePath(
CriteriaBuilderImpl criteriaBuilder,
Class<X> javaType,
PathSource pathSource,
SingularAttribute<?, X> attribute) {
super( criteriaBuilder, javaType, pathSource );
this.attribute = attribute;
this.managedType = resolveManagedType( attribute );
}
private ManagedType<X> resolveManagedType(SingularAttribute<?, X> attribute) {
if ( Attribute.PersistentAttributeType.BASIC == attribute.getPersistentAttributeType() ) {
return null;
}
else if ( Attribute.PersistentAttributeType.EMBEDDED == attribute.getPersistentAttributeType() ) {
return (EmbeddableType<X>) attribute.getType();
}
else {
return (IdentifiableType<X>) attribute.getType();
// return criteriaBuilder.getEntityManagerFactory()
// .getMetamodel()
// .managedType( javaType );
}
}
/**
* {@inheritDoc}
*/
public SingularAttribute<?, X> getAttribute() {
return attribute;
}
/**
* {@inheritDoc}
*/
public Bindable<X> getModel() {
return getAttribute();
}
/**
* {@inheritDoc}
*/
@Override
protected boolean canBeDereferenced() {
return managedType != null;
}
@Override
protected Attribute locateAttributeInternal(String attributeName) {
final Attribute attribute = managedType.getAttribute( attributeName );
// ManagedType.getAttribute should throw exception rather than return
// null, but just to be safe...
if ( attribute == null ) {
throw new IllegalArgumentException( "Could not resolve attribute named " + attributeName );
}
return attribute;
}
}

View File

@ -75,7 +75,7 @@ public class BooleanAssertionPredicate
* {@inheritDoc}
*/
public String render(CriteriaQueryCompiler.RenderingContext renderingContext) {
final String operator = isNegated() ? " = " : " <> ";
final String operator = isNegated() ? " <> " : " = ";
final String assertionLiteral = assertedValue ? "true" : "false";
return ( (Renderable) expression ).render( renderingContext )

View File

@ -28,8 +28,8 @@ import java.util.Collection;
import org.hibernate.ejb.criteria.ParameterRegistry;
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;
import org.hibernate.ejb.criteria.path.PluralAttributePath;
/**
* Models an <tt>IS [NOT] EMPTY</tt> restriction
@ -40,17 +40,17 @@ public class IsEmptyPredicate<C extends Collection>
extends AbstractSimplePredicate
implements UnaryOperatorExpression<Boolean>, Serializable {
private final CollectionExpression<C> collectionExpression;
private final PluralAttributePath<C> collectionPath;
public IsEmptyPredicate(
CriteriaBuilderImpl criteriaBuilder,
CollectionExpression<C> collectionExpression) {
PluralAttributePath<C> collectionPath) {
super( criteriaBuilder );
this.collectionExpression = collectionExpression;
this.collectionPath = collectionPath;
}
public CollectionExpression<C> getOperand() {
return collectionExpression;
public PluralAttributePath<C> getOperand() {
return collectionPath;
}
public void registerParameters(ParameterRegistry registry) {

View File

@ -30,8 +30,8 @@ import org.hibernate.ejb.criteria.ParameterRegistry;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
import org.hibernate.ejb.criteria.CriteriaQueryCompiler;
import org.hibernate.ejb.criteria.Renderable;
import org.hibernate.ejb.criteria.expression.CollectionExpression;
import org.hibernate.ejb.criteria.expression.LiteralExpression;
import org.hibernate.ejb.criteria.path.PluralAttributePath;
/**
* Models an <tt>[NOT] MEMBER OF</tt> restriction
@ -43,30 +43,30 @@ public class MemberOfPredicate<E, C extends Collection<E>>
implements Serializable {
private final Expression<E> elementExpression;
private final CollectionExpression<C> collectionExpression;
private final PluralAttributePath<C> collectionPath;
public MemberOfPredicate(
CriteriaBuilderImpl criteriaBuilder,
Expression<E> elementExpression,
CollectionExpression<C> collectionExpression) {
PluralAttributePath<C> collectionPath) {
super( criteriaBuilder );
this.elementExpression = elementExpression;
this.collectionExpression = collectionExpression;
this.collectionPath = collectionPath;
}
public MemberOfPredicate(
CriteriaBuilderImpl criteriaBuilder,
E element,
CollectionExpression<C> collectionExpression) {
PluralAttributePath<C> collectionPath) {
this(
criteriaBuilder,
new LiteralExpression<E>( criteriaBuilder, element ),
collectionExpression
collectionPath
);
}
public CollectionExpression<C> getCollectionExpression() {
return collectionExpression;
public PluralAttributePath<C> getCollectionPath() {
return collectionPath;
}
public Expression<E> getElementExpression() {
@ -74,14 +74,14 @@ public class MemberOfPredicate<E, C extends Collection<E>>
}
public void registerParameters(ParameterRegistry registry) {
Helper.possibleParameter( getCollectionExpression(), registry );
Helper.possibleParameter( getCollectionPath(), registry );
Helper.possibleParameter( getElementExpression(), registry );
}
public String render(CriteriaQueryCompiler.RenderingContext renderingContext) {
return ( (Renderable) elementExpression ).render( renderingContext )
+ ( isNegated() ? " not" : "" ) + " member of "
+ collectionExpression.render( renderingContext );
+ getCollectionPath().render( renderingContext );
}
public String renderProjection(CriteriaQueryCompiler.RenderingContext renderingContext) {

View File

@ -0,0 +1,62 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.ejb.criteria.paths;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.Root;
import org.hibernate.ejb.metamodel.AbstractMetamodelSpecificTest;
import org.hibernate.ejb.metamodel.LineItem;
import org.hibernate.ejb.metamodel.LineItem_;
import org.hibernate.ejb.metamodel.Order;
import org.hibernate.ejb.metamodel.Order_;
/**
* TODO : javadoc
*
* @author Steve Ebersole
*/
public class ImplicitJoinTest extends AbstractMetamodelSpecificTest {
public void testImplicitJoinFromExplicitCollectionJoin() {
EntityManager em = getOrCreateEntityManager();
em.getTransaction().begin();
CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();
CriteriaQuery<Order> criteria = criteriaBuilder.createQuery( Order.class );
Root<Order> orderRoot = criteria.from( Order.class );
Join<Order, LineItem> lineItemsJoin = orderRoot.join( Order_.lineItems );
criteria.where( criteriaBuilder.lt( lineItemsJoin.get( LineItem_.quantity ), 2 ) );
criteria.select( orderRoot ).distinct( true );
TypedQuery<Order> query = em.createQuery( criteria );
query.getResultList();
em.getTransaction().commit();
em.close();
}
}

View File

@ -0,0 +1,42 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.ejb.metamodel;
import org.hibernate.ejb.test.TestCase;
/**
* TODO : javadoc
*
* @author Steve Ebersole
*/
public abstract class AbstractMetamodelSpecificTest extends TestCase {
@Override
public Class[] getAnnotatedClasses() {
return new Class[] {
Address.class, Alias.class, Country.class, CreditCard.class, Customer.class,
Info.class, LineItem.class, Order.class, Phone.class, Product.class,
ShelfLife.class, Spouse.class
};
}
}