【问题标题】:JPQL IN operator in DELETE query with 2-deep relationship WHERE clauseJPQL IN 运算符在 DELETE 查询中具有 2 深关系 WHERE 子句
【发布时间】:2021-01-24 18:58:20
【问题描述】:

我有一个这样的 JPQL 查询:

    @Modifying
    @Query("delete from Thing t where t.manyToOne1.manyToOne2 = :farThing and t.id in :ids")
    void delete(ManyToOne2 manyToOne2, List<String> ids);

导致异常:

Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'cross join many_to_one1 manytoone1_ where manytoone2_id=1039 and (id in (' at line 1

【问题讨论】:

    标签: java spring-boot hibernate spring-data-jpa jpql


    【解决方案1】:

    将请求更改为

        @Modifying
        @Query("delete from Thing t where t.manyToOne1 = :manyToOne1 and t.id in :ids")
        void delete(ManyToOne1 manyToOne1, List<String> ids);
    

    解决了这个问题。

    从理论上讲,对其他一些请求使用 2 深的多对一关系链似乎没有错,但与 IN 运算符或修改查询结合使用在实践中是行不通的。

    【讨论】:

      【解决方案2】:

      问题是,这种查询使用隐式连接,会在 DML 语句中生成 SQL 连接。并非所有 DBMS 都允许这样做,而且 Hibernate 尚不支持此操作。如您所见,您可以避免隐式连接。对于删除语句,您还可以使用存在子查询来对连接进行建模,如下所示:

      delete from Thing t 
      where t.id in :ids
        and exists (
          select 1 
          from t.manyToOne1 a
          where a.manyToOne2 = :farThing
      )
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-01-10
        • 2020-10-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-05-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多