jsr338-experts@jpa-spec.java.net

[jsr338-experts] Re: criteria API bulk update/delete

From: Werner Keil <werner.keil_at_gmx.net>
Date: Fri, 29 Apr 2011 09:48:01 +0200

Linda/all,

A brief reply inline.

Beside I guess many of you noticed the JavaOne US CFP by now.
Unlike JavaOne India in about two weeks where I plan to spend one day going to the US conference depends largely on my project work then. I cannot predict that so early in the year, but being EC member I guess I am entitled a free pass at least regardless of any presentations. So for a presentation of the JSR I'd be happy to attend or even co-present or consider a F2F meeting if enough EG members are able to attend.

Werner
 
-------- Original-Nachricht --------
> Datum: Thu, 28 Apr 2011 13:10:53 -0700
> Von: Linda DeMichiel <linda.demichiel_at_oracle.com>
> An: jsr338-experts_at_jpa-spec.java.net
> Betreff: [jsr338-experts] Re: criteria API bulk update/delete

>
>
> On 4/28/2011 4:04 AM, Emmanuel Bernard wrote:
> > I haven't fired up my compiler nor spent too much time on it but could
> we get rid of the T param in CommonAbstractQuery (now CriteriaBase)? I can't
> seem to find what type-safety purpose it plays.
> > What I do not like is that T in CommonAbstractQuery and T in
> AbstractQuery have different meanings (which smells like something we will regret
> later on).
> >
>
> Yes -- I think this would send a clearer message.
>

Sounds good, if they mean something different, using a different generic name seems good.

> > We might be able to override from() in CriteriaDelete and CriteriaUpdate
> subclasses if you really want to bind them to a type
> >
>
> That would make more sense with regard to the typing of the interfaces.
> The other
> consequence would be to enforce a root over just that type.
>
> -Linda
>
> > class CriteriaDelete<T> extends CriteriaBase {
> > Root<T> from(Class<T> entityClass);
> > }
> >
> > Otherwise name wise, CriteriaBase, AbstractQuery (existing)
> CriteriaUpdate CriteriaDelete seem quite natural to me.
> >
> > Emmanuel
> >
> > On 28 mars 2011, at 20:53, Linda DeMichiel wrote:
> >
> >> One of the features of JPQL that the criteria API lacks is the
> >> ability to issue bulk updates and deletes.
> >>
> >> Here's a cut at a strawman API for update and delete criteria queries.
> >> There are a number of issues here that are in need of feedback.
> >>
> >> There are 3 new interfaces, which I've attached to the message:
> >> UpdateQuery
> >> DeleteQuery
> >> CommonAbstractQuery
> >>
> >> I spent a long time mulling over whether to introduce a new type to
> >> model the target (i.e. entity/table) of the update operation because
> >> of the restricted semantics of bulk operation targets in SQL (i.e.,
> >> single table, no derived joins in the UPDATE clause) or whether to
> >> reuse Root. In the end, I decided to reuse Root, because of the
> >> extensions that many databases provide to support joins. In this
> >> case, the joined item is not itself updatable, but is used in the
> >> expression of constraints or as a source of new values. However, we
> >> will need to decide exactly what we state in terms of what is
> >> "defined" vs "undefined" in the spec. Probably the most conservative
> >> statement would be to state that the use of more than one root and/or
> >> the use of joins is undefined.
> >>
> >> Another issue is whether UpdateQuery and DeleteQuery should exist in
> >> any form of inheritance hierarchy to allow common information to be
> >> factored out. I've done this in the interfaces attached to this
> >> message. (The root of the factored hierarchy could certainly use a
> >> better name, however.)
> >>
> >>
> >> The CriteriaBuilder interface would be extended with methods
> >> like:
> >>
> >> <T> UpdateQuery<T> createUpdateQuery(Class<T> targetEntity);
> >> <T> UpdateQuery<T> createUpdateQuery(EntityType<T> targetEntity);
> >> <T> DeleteQuery<T> createDeleteQuery(Class<T> targetEntity);
> >> <T> DeleteQuery<T> createDeleteQuery(EntityType<T> targetEntity);
> >>
> >> And the EntityManager interface would be extended with methods like:
> >>
> >> public <T> TypedQuery createQuery(UpdateQuery<T> updateQuery)
> >> public <T> TypedQuery createQuery(DeleteQuery<T> deleteQuery)
> >>
> >>
> >> Example queries:
> >>
> >> // Simple Update
> >>
> >> UpdateQuery<Customer> q1 = cb.createUpdateQuery(Customer.class);
> >> Root<Customer> c1 = q1.from(Customer.class);
> >> q1.set(c1.get(Customer_.firstName), "Fred")
> >> .set(c1.get(Customer_.lastName), "Jones")
> >> .where(cb.equal(c1.get(Customer_.id), 1));
> >>
> >>
> >> // Simple Delete
> >>
> >> DeleteQuery<Customer> q2 = cb.createDeleteQuery(Customer.class);
> >> Root<Customer> c2 = q2.from(Customer.class);
> >> q2.where(cb.equal(c2.get(Customer_.id), 5));
> >>
> >>
> >> // Bulk Update
> >>
> >> UpdateQuery<Employee> q3 = cb.createUpdateQuery(Employee.class);
> >> Root<Employee> e3 = q3.from(Employee.class);
> >> q3.set(e3.get(Employee_.salary),
> >> cb.prod(e3.get(Employee_.salary), 1.1).as(BigDecimal.class))
> >> .where(cb.equal(e3.get(Employee_.dept).get(Department_.name),
> "Sales"));
> >>
> >>
> >> // Bulk Delete
> >>
> >> DeleteQuery<Employee> q4 = cb.createDeleteQuery(Employee.class);
> >> Root<Employee> e4 = q4.from(Employee.class);
> >> q4.where(cb.equal(e4.type(), Exempt.class));
> >>
> >>
> >> //Update query with multiple levels
> >>
> >> UpdateQuery<Customer> q5 = cb.createUpdateQuery(Customer.class);
> >> Root<Customer> c5 = q5.from(Customer.class);
> >> q5.set(c5.get(Customer_.address).get(Address_.city), "NewYork")
> >> .set(c5.get(Customer_.address).get(Address_.state), "NewYork")
> >> .where(cb.equal(c5.get(Customer_.id), 1));
> >>
> >>
> >> Opinions, please.....
> >>
> >> thanks,
> >>
> >> -Linda
> >> package javax.persistence.criteria;
> >>
> >> import javax.persistence.metamodel.SingularAttribute;
> >>
> >> public interface UpdateQuery<T> extends CommonAbstractQuery<T> {
> >>
> >> Root<T> getRoot();
> >>
> >> <Y> UpdateQuery<T> set(SingularAttribute<? super T, Y> attribute, Y
> value);
> >>
> >> <Y> UpdateQuery<T> set(SingularAttribute<? super T, Y> attribute,
> >> Expression<? extends Y> value);
> >>
> >> <Y> UpdateQuery<T> set(Path<Y> attribute, Y value);
> >>
> >> <Y> UpdateQuery<T> set(Path<Y> attribute, Expression<? extends Y>
> value);
> >>
> >> UpdateQuery<T> where(Expression<Boolean> restriction);
> >>
> >> UpdateQuery<T> where(Predicate... restrictions);
> >>
> >> }
> >> package javax.persistence.criteria;
> >>
> >> public interface DeleteQuery<T> extends CommonAbstractQuery<T> {
> >>
> >> Root<T> getRoot();
> >>
> >> DeleteQuery<T> where(Expression<Boolean> restriction);
> >>
> >> DeleteQuery<T> where(Predicate... restrictions);
> >>
> >> }
> >>
> >> package javax.persistence.criteria;
> >>
> >> import java.util.List;
> >> import java.util.Set;
> >>
> >> import javax.persistence.metamodel.EntityType;
> >>
> >> /**
> >> * The <code>CommonAbstractQuery</code> interface defines functionality
> >> * that is common to update and delete criteria operations ("update
> >> * queries" and "delete queries" and to both top-level queries and
> >> * subqueries.
> >> * It is not intended to be used directly in query construction.
> >> *
> >> * <p> All queries must have:
> >> * a set of root entities
> >> * <p> All queries may have:
> >> * a conjunction of restrictions.
> >> *
> >> * @param <T> the type of the query
> >> *
> >> * @since Java Persistence 2.1
> >> */
> >> public interface CommonAbstractQuery<T> {
> >>
> >> /**
> >> * Create and add a query root corresponding to the given entity,
> >> * forming a cartesian product with any existing roots.
> >> * @param entityClass the entity class
> >> * @return query root corresponding to the given entity
> >> */
> >> <X> Root<X> from(Class<X> entityClass);
> >>
> >> /**
> >> * Create and add a query root corresponding to the given entity,
> >> * forming a cartesian product with any existing roots.
> >> * @param entity metamodel entity representing the entity
> >> * of type X
> >> * @return query root corresponding to the given entity
> >> */
> >> <X> Root<X> from(EntityType<X> entity);
> >>
> >> /**
> >> * Modify the query to restrict the query results according
> >> * to the specified boolean expression.
> >> * Replaces the previously added restriction(s), if any.
> >> * @param restriction a simple or compound boolean expression
> >> * @return the modified query
> >> */
> >> CommonAbstractQuery<T> where(Expression<Boolean> restriction);
> >>
> >> /**
> >> * Modify the query to restrict the query results according
> >> * to the conjunction of the specified restriction predicates.
> >> * Replaces the previously added restriction(s), if any.
> >> * If no restrictions are specified, any previously added
> >> * restrictions are simply removed.
> >> * @param restrictions zero or more restriction predicates
> >> * @return the modified query
> >> */
> >> CommonAbstractQuery<T> where(Predicate... restrictions);
> >>
> >> /**
> >> * Create a subquery of the query.
> >> * @param type the subquery result type
> >> * @return subquery
> >> */
> >> <U> Subquery<U> subquery(Class<U> type);
> >>
> >> /**
> >> * Return the predicate that corresponds to the where clause
> >> * restriction(s), or null if no restrictions have been
> >> * specified.
> >> * @return where clause predicate
> >> */
> >> Predicate getRestriction();
> >>
> >>
> >> }
> >>
> >> package javax.persistence.criteria;
> >>
> >> import java.util.List;
> >> import java.util.Set;
> >>
> >> import javax.persistence.metamodel.EntityType;
> >>
> >> /**
> >> * The <code>AbstractQuery</code> interface defines functionality that
> is common
> >> * to both top-level queries and subqueries.
> >> * It is not intended to be used directly in query construction.
> >> *
> >> * <p> All queries must have:
> >> * a set of root entities (which may in turn own joins).
> >> * <p> All queries may have:
> >> * a conjunction of restrictions.
> >> *
> >> * @param <T> the type of the result
> >> *
> >> * @since Java Persistence 2.0
> >> */
> >> public interface AbstractQuery<T> extends CommonAbstractQuery<T> {
> >>
> >> /**
> >> * Modify the query to restrict the query results according
> >> * to the specified boolean expression.
> >> * Replaces the previously added restriction(s), if any.
> >> * @param restriction a simple or compound boolean expression
> >> * @return the modified query
> >> */
> >> AbstractQuery<T> where(Expression<Boolean> restriction);
> >>
> >> /**
> >> * Modify the query to restrict the query results according
> >> * to the conjunction of the specified restriction predicates.
> >> * Replaces the previously added restriction(s), if any.
> >> * If no restrictions are specified, any previously added
> >> * restrictions are simply removed.
> >> * @param restrictions zero or more restriction predicates
> >> * @return the modified query
> >> */
> >> AbstractQuery<T> where(Predicate... restrictions);
> >>
> >> /**
> >> * Specify the expressions that are used to form groups over
> >> * the query results.
> >> * Replaces the previous specified grouping expressions, if any.
> >> * If no grouping expressions are specified, any previously
> >> * added grouping expressions are simply removed.
> >> * @param grouping zero or more grouping expressions
> >> * @return the modified query
> >> */
> >> AbstractQuery<T> groupBy(Expression<?>... grouping);
> >>
> >> /**
> >> * Specify the expressions that are used to form groups over
> >> * the query results.
> >> * Replaces the previous specified grouping expressions, if any.
> >> * If no grouping expressions are specified, any previously
> >> * added grouping expressions are simply removed.
> >> * @param grouping list of zero or more grouping expressions
> >> * @return the modified query
> >> */
> >> AbstractQuery<T> groupBy(List<Expression<?>> grouping);
> >>
> >> /**
> >> * Specify a restriction over the groups of the query.
> >> * Replaces the previous having restriction(s), if any.
> >> * @param restriction a simple or compound boolean expression
> >> * @return the modified query
> >> */
> >> AbstractQuery<T> having(Expression<Boolean> restriction);
> >>
> >> /**
> >> * Specify restrictions over the groups of the query
> >> * according the conjunction of the specified restriction
> >> * predicates.
> >> * Replaces the previously having added restriction(s), if any.
> >> * If no restrictions are specified, any previously added
> >> * restrictions are simply removed.
> >> * @param restrictions zero or more restriction predicates
> >> * @return the modified query
> >> */
> >> AbstractQuery<T> having(Predicate... restrictions);
> >>
> >> /**
> >> * Specify whether duplicate query results will be eliminated.
> >> * A true value will cause duplicates to be eliminated.
> >> * A false value will cause duplicates to be retained.
> >> * If distinct has not been specified, duplicate results must
> >> * be retained.
> >> * @param distinct boolean value specifying whether duplicate
> >> * results must be eliminated from the query result or
> >> * whether they must be retained
> >> * @return the modified query
> >> */
> >> AbstractQuery<T> distinct(boolean distinct);
> >>
> >> /**
> >> * Return the query roots. These are the roots that have
> >> * been defined for the <code>CriteriaQuery</code> or
> <code>Subquery</code> itself,
> >> * including any subquery roots defined as a result of
> >> * correlation. Returns empty set if no roots have been defined.
> >> * Modifications to the set do not affect the query.
> >> * @return the set of query roots
> >> */
> >> Set<Root<?>> getRoots();
> >>
> >> /**
> >> * Return the selection of the query, or null if no selection
> >> * has been set.
> >> * @return selection item
> >> */
> >> Selection<T> getSelection();
> >>
> >> /**
> >> * Return a list of the grouping expressions. Returns empty
> >> * list if no grouping expressions have been specified.
> >> * Modifications to the list do not affect the query.
> >> * @return the list of grouping expressions
> >> */
> >> List<Expression<?>> getGroupList();
> >>
> >> /**
> >> * Return the predicate that corresponds to the restriction(s)
> >> * over the grouping items, or null if no restrictions have
> >> * been specified.
> >> * @return having clause predicate
> >> */
> >> Predicate getGroupRestriction();
> >>
> >> /**
> >> * Return whether duplicate query results must be eliminated or
> >> * retained.
> >> * @return boolean indicating whether duplicate query results
> >> * must be eliminated
> >> */
> >> boolean isDistinct();
> >>
> >> /**
> >> * Return the result type of the query or subquery. If a result
> >> * type was specified as an argument to the
> >> * <code>createQuery</code> or <code>subquery</code> method, that
> >> * type will be returned. If the query was created using the
> >> * <code>createTupleQuery</code> method, the result type is
> >> * <code>Tuple</code>. Otherwise, the result type is
> >> * <code>Object</code>.
> >> * @return result type
> >> */
> >> Class<T> getResultType();
> >> }
> >

-- 
GMX DSL Doppel-Flat ab 19,99 Euro/mtl.! Jetzt mit 
gratis Handy-Flat! http://portal.gmx.net/de/go/dsl