【问题标题】:Spring JPA repository generates wrong native query for update clauseSpring JPA 存储库为更新子句生成错误的本机查询
【发布时间】:2020-01-04 18:56:33
【问题描述】:

我正在尝试使用以下方法更新我的实体列:

@Modifying
@Query("update Person person set person.hixNumber = :hixNumber , "
        + "fixNumber.fixNumber = :fixNumber where person.role.type = 'ADMIN'")
int updatePersonByRole(@Param("hixNumber ") int hixNumber , @Param("fixNumber ") int fixNumber);

此方法给出异常原因:

原因:org.postgresql.util.PSQLException: ERROR: syntax error at 或靠近“十字架”

因为生成的原生查询是错误的:

update person cross join set hix_humber=?, set fix_humber=? where type=?

我的 Person 实体类如下所示:

@Getter
@Setter
@Entity
@NoArgsConstructor
public class Person {

    @EmbeddedId
    private PersonId personId;

    @MapsId("roleId")
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "role_id", insertable = false, updatable = false)
    private Role role;

    @MapsId("storeId")
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "store_id", insertable = false, updatable = false)
    private Store store;

    private int hixNumber;

    private int fixNumber;
}

和主键实体:

@Getter
@Setter
@EqualsAndHashCode
@Embeddable
public class Personid implements Serializable {

    private Long roleId;

    private Long storeId;
}

我做错了什么?谢谢。

【问题讨论】:

  • Person 和 Role 的关系是什么?怎么注释的?
  • 向我们展示可嵌入的 PersonId
  • @MaciejKowalski 还添加了 personId

标签: hibernate jpa spring-data-jpa jpql spring-repositories


【解决方案1】:

我认为问题在于您间接尝试引用依赖实体Role。这需要在更新语句中使用JOIN,它在本机查询中不能很好地翻译。

尝试使用子查询,这可能会更好地转换为本机查询:

update Person person 
set person.hixNumber = :hixNumber,
    person.fixNumber = :fixNumber 
where exists (
      select personSub.id 
      from Person personSub
        inner join personSub.role r 
      where person.id = personSub.id 
          and r.type = 'ADMIN'"
    )

【讨论】:

    【解决方案2】:

    这可能是问题所在:where person.role.type = 'ADMIN'".
    这里person 是一个实体,role 是另一个。当您将where 子句应用于实体关系的字段时,这意味着您要求JPA 在personrole 之间执行连接。问题是您不能在更新 JPA 查询中使用 join

    您可能感兴趣的一些 SO 参考资料:

    要绕过该限制,您应该使用一个子查询,该子查询不是连接,而是此上下文中的有效替代方案。例如类似的东西:

    @Query("update Person person set person.hixNumber = :hixNumber , "
            + "fixNumber.fixNumber = :fixNumber where " 
            + "person.roleId in (select r.roleId from role r where r.type = 'ADMIN')")
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-03-28
      • 2015-10-13
      • 2014-12-27
      • 1970-01-01
      • 1970-01-01
      • 2019-06-17
      • 1970-01-01
      • 2021-04-16
      相关资源
      最近更新 更多