JPQL 查询删除不接受声明的 JOIN?
JPQL query delete not accept a declared JOIN?
我试图理解为什么 Hibernate 不接受这个遵循 JPQL:
@Modifying
@Query("delete from Order order JOIN order.credit credit WHERE credit.id IN ?1")
void deleteWithListaIds(List<Long> ids);
我收到的错误是:
Caused by: java.lang.IllegalArgumentException: node to traverse cannot be null!
at org.hibernate.hql.internal.ast.util.NodeTraverser.traverseDepthFirst(NodeTraverser.java:46)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.parse(QueryTranslatorImpl.java:284)
但接受这个:
@Modifying
@Query("delete from Order order WHERE order.credit.id IN ?1")
void deleteWithListaIds(List<Long> ids);
实体Order
(实体Credit
不映射Order
):
@Entity
public class Order {
@Id
@Setter
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = SEQUENCE)
@SequenceGenerator(name = SEQUENCE, sequenceName = SEQUENCE, allocationSize = 1)
@Column(name = "id", nullable = false)
private Long id;
@JoinColumn(name = "credit_id", foreignKey = @ForeignKey(name = "fk_order_credit"))
@ManyToOne(fetch = FetchType.LAZY, optional = false)
private Credit credit;
}
在 select
语句中,两种方法都被接受,但我不明白为什么 Hibernate 有这个限制,或者如果我在我的 DELETE Jpql 中做错了什么。我想在查询中声明 JOIN。
我知道在更复杂的查询中解决此问题的唯一方法是创建子选择:
delete from Order order WHERE order.id IN (
SELECT order.id FROM Order order
JOIN order.credit credit
WHERE credit.id in ?1)
对于更复杂的删除查询,这是正确的方法吗?
我在上面的代码中使用了 Spring Jpa 存储库和 Spring Boot 1.5.10.RELEASE.
I don't understand why Hibernate have this limitation.
在第 4.10 节的 JPA Spec 中这样指定:
delete_statement ::= delete_clause [where_clause]
delete_clause ::= DELETE FROM entity_name [[AS] identification_variable]
因此删除语句中不允许加入。
为什么这样决定是我这边的纯粹猜测。
但是 select_clause
或 delete_clause
指定查询操作的对象。虽然 select 语句对多个实体的组合进行操作完全没问题,但用于删除的连接并没有多大意义。
它只是强制您指定要删除的实体。
The only way that I know to resolve this problem in more complex queries is to create a subselect:
Is this the right approach for more complex delete queries?
如果你不能用更简单的方式表达它,那么是的,这就是要走的路。
我试图理解为什么 Hibernate 不接受这个遵循 JPQL:
@Modifying
@Query("delete from Order order JOIN order.credit credit WHERE credit.id IN ?1")
void deleteWithListaIds(List<Long> ids);
我收到的错误是:
Caused by: java.lang.IllegalArgumentException: node to traverse cannot be null!
at org.hibernate.hql.internal.ast.util.NodeTraverser.traverseDepthFirst(NodeTraverser.java:46)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.parse(QueryTranslatorImpl.java:284)
但接受这个:
@Modifying
@Query("delete from Order order WHERE order.credit.id IN ?1")
void deleteWithListaIds(List<Long> ids);
实体Order
(实体Credit
不映射Order
):
@Entity
public class Order {
@Id
@Setter
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = SEQUENCE)
@SequenceGenerator(name = SEQUENCE, sequenceName = SEQUENCE, allocationSize = 1)
@Column(name = "id", nullable = false)
private Long id;
@JoinColumn(name = "credit_id", foreignKey = @ForeignKey(name = "fk_order_credit"))
@ManyToOne(fetch = FetchType.LAZY, optional = false)
private Credit credit;
}
在 select
语句中,两种方法都被接受,但我不明白为什么 Hibernate 有这个限制,或者如果我在我的 DELETE Jpql 中做错了什么。我想在查询中声明 JOIN。
我知道在更复杂的查询中解决此问题的唯一方法是创建子选择:
delete from Order order WHERE order.id IN (
SELECT order.id FROM Order order
JOIN order.credit credit
WHERE credit.id in ?1)
对于更复杂的删除查询,这是正确的方法吗?
我在上面的代码中使用了 Spring Jpa 存储库和 Spring Boot 1.5.10.RELEASE.
I don't understand why Hibernate have this limitation.
在第 4.10 节的 JPA Spec 中这样指定:
delete_statement ::= delete_clause [where_clause]
delete_clause ::= DELETE FROM entity_name [[AS] identification_variable]
因此删除语句中不允许加入。
为什么这样决定是我这边的纯粹猜测。
但是 select_clause
或 delete_clause
指定查询操作的对象。虽然 select 语句对多个实体的组合进行操作完全没问题,但用于删除的连接并没有多大意义。
它只是强制您指定要删除的实体。
The only way that I know to resolve this problem in more complex queries is to create a subselect:
Is this the right approach for more complex delete queries?
如果你不能用更简单的方式表达它,那么是的,这就是要走的路。