我有以下实体,需要更新特定字段中的字段,其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)
答案 0 :(得分:1)
为什么不将您的关联双向化?
将其添加到您的CartItem
实体:
@ManyToOne
private Cart cart;
在mappedBy
cartItem
上Cart
设置@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
答案 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)");