使用hibernate的查询更新运行到QueryException:无法解析路径

时间:2014-03-10 03:08:20

标签: java hibernate hibernate-mapping

我有以下实体,需要更新特定字段中的字段,其removedDate为null。但是以下代码返回异常。

@Entity
public class Cart implements Serializable {

    @Id
    @GeneratedValue
    private Long id;

    @OneToMany(cascade = CascadeType.ALL)
    @LazyCollection(LazyCollectionOption.FALSE)
    private List<CartItem> items;

    public Cart() {
    }

     getters and setters

}

@Entity
public class CartItem {

    @Id
    @GeneratedValue
    private long id;

    @ManyToOne
    private Product pro;

    @Temporal(javax.persistence.TemporalType.TIMESTAMP)
    private Date addedDate;

    @Temporal(javax.persistence.TemporalType.TIMESTAMP)
    private Date removedDate;

    getters and setters

}

Hibernate Code 1

Query query = session.createQuery("UPDATE CartItem SET removedDate = :currentDateTime "
                        + " WHERE CartItem.id IN (Select Cart.items.id From Cart"
                        + " WHERE Cart.id = :cartId"
                        + " AND Cart.items.pro.id = :pro"
                        + " AND Cart.items.removedDate is null)");
query.setParameter("currentDateTime", dt.getCurrentDateTime());
query.setParameter("cartId", cartId);
query.setParameter("pro", proId);

int result = query.executeUpdate();

代码1例外

SEVERE:   org.hibernate.QueryException: Unable to resolve path [CartItem.id], unexpected 
          token [CartItem] [UPDATE com.myproject.CartItem SET removedDate = 
           :currentDateTime  WHERE CartItem.id IN (Select Cart.items.id From 
           com.myproject.Cart WHERE Cart.id = :cartId AND cart.items.pro.id = :proId 
           AND Cart.items.removedDate is null))]
    at org.hibernate.hql.internal.ast.tree.IdentNode.resolveAsNakedComponentPropertyRefLHS(IdentNode.java:245)
    at org.hibernate.hql.internal.ast.tree.IdentNode.resolve(IdentNode.java:110)
    at org.hibernate.hql.internal.ast.tree.DotNode.resolveFirstChild(DotNode.java:177)
    at org.hibernate.hql.internal.ast.HqlSqlWalker.lookupProperty(HqlSqlWalker.java:577)
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.addrExpr(HqlSqlBaseWalker.java:4719)

Hibernate Code 2

  Query query = session.createQuery("UPDATE CartItem SET removedDate = :currentDateTime "
                        + " WHERE id IN (Select items.id From Cart"
                        + " WHERE id = :CartId"
                        + " AND items.pro.id = :pro"
                        + " AND items.removedDate is null)");

代码2例外

SEVERE:   org.hibernate.QueryException: illegal attempt to dereference collection 
          [{synthetic-alias}{non-qualified-property-ref}items] with element property 
          reference [id] [UPDATE com.myproject.CartItem SET removedDate = 
          :currentDateTime  WHERE id IN (Select items.id From com.myproject.Cart WHERE 
          id = :cartId AND items.pro.id = :pro AND items.removedDate is null)]
    at org.hibernate.hql.internal.ast.tree.DotNode$1.buildIllegalCollectionDereferenceException(DotNode.java:68)
at org.hibernate.hql.internal.ast.tree.DotNode.checkLhsIsNotCollection(DotNode.java:550)
at org.hibernate.hql.internal.ast.tree.DotNode.resolve(DotNode.java:246)
at org.hibernate.hql.internal.ast.tree.FromReferenceNode.resolve(FromReferenceNode.java:118)
at org.hibernate.hql.internal.ast.tree.FromReferenceNode.resolve(FromReferenceNode.java:114)

4 个答案:

答案 0 :(得分:1)

为什么不将您的关联双向化?
将其添加到您的CartItem实体:

@ManyToOne
private Cart cart;

mappedBy cartItemCart设置@OneToMany(cascade = CascadeType.ALL, mappedBy="cart") @LazyCollection(LazyCollectionOption.FALSE) private List<CartItem> items;

"UPDATE CartItem c SET c.removedDate = :currentDateTime "
            + " WHERE c.cart.id = :cartId" 
            + " AND c.pro.id = :pro"
            + " AND c.removedDate is null"

生成的HQL会更简单(并且应该可以):

{{1}}

答案 1 :(得分:0)

通过在内部选择查询中添加别名来尝试此操作。

  Query query = session.createQuery("UPDATE CartItem SET removedDate = :currentDateTime "
                        + " WHERE id IN (Select cart.items.id From Cart cart"
                        + " WHERE cart.id = :CartId"
                        + " AND cart.items.pro.id = :pro"
                        + " AND cart.items.removedDate is null)");

编辑2 我做了一些阅读,发现object.collection.id仅适用于1:1或N:1关系,而不适用于1:N关系,这就是你所拥有的。试试这个。

SELECT items.id
FROM Cart cart
LEFT JOIN cart.items items
WHERE cart.id = :CartId AND items.pro.id = :pro AND items.removedDate is null

以下是infoinfoinfo

答案 2 :(得分:0)

感谢Hrishikesh的评论,我通过提供确切的SQLQuery找到答案。

UPDATE cartItem SET removedDate = :currentDateTime"
                        + " WHERE pro = :pro"
                        + " AND removedDate IS NULL"
                        + " AND id IN 
                            ( SELECT items_id from Cart_CartItem WHERE Cart_id = :CartId)

答案 3 :(得分:-1)

试试:

    Query query = session.createQuery("UPDATE CartItem SET removedDate = :currentDateTime "
                    + " WHERE id IN (Select ci.id From Cart c inner join c.items ci"
                    + " WHERE c.id = :cartId"
                    + " AND ci.pro.id = :pro"
                    + " AND ci.removedDate is null)");