我使用spring-jpa和hibernate实现。我使用mariadb,我尝试做一个更新子查询
我的对象结构
@Entity
public class Room {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long roomId;
@ManyToOne
@JoinColumn(name = "appartment_id")
private Appartment appartment;
}
@Entity
public class Appartment {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long appartmentId;
@OneToMany
@JoinColumn(name="appartment_id")
private Set<Room> roomList;
}
update Room r1
set r1.available = :availability
where r1.roomId in
( select r2.roomId from Room r2 JOIN r2.appartment a1 WHERE a1.appartmentId = :appartmentId )
我收到此错误
java.sql.SQLException:表&#39;房间&#39;被指定两次,两者都作为&#39;更新&#39;的目标。并作为数据的单独来源
答案 0 :(得分:3)
这是MySQL的限制: -
http://dev.mysql.com/doc/refman/5.7/en/update.html
您无法更新表并从子查询中的同一个表中进行选择。
你可以做一个软糖有时候做隐藏子查询的另一级子查询可能有效。这样的事情(未经测试): -
UPDATE Room r1
SET r1.available = :availability
WHERE r1.roomId IN
SELECT roomId
FROM
(
SELECT r2.roomId
FROM Room r2
JOIN r2.appartment a1
WHERE a1.appartmentId = :appartmentId
)
请注意,您的查询可能有错误。在子查询中,您将表名为r2的表连接到名为r2的数据库上名为appartment的表。此外,您的子查询在没有连接条件的情况下执行JOIN。
但是你很可能只需要在UPDATE语句中进行连接而不需要子查询: -
UPDATE Room
INNER JOIN r2.appartment a1
ON Room.roomId = a1.roomId
SET r1.available = :availability
WHERE a1.appartmentId = :appartmentId
答案 1 :(得分:0)
一个解决方案是单独选择 roomIds
并将它们作为参数传递。
选择 ID 列表
List<Long> roomIdList = entityManager.createQuery(
"""SELECT r2.roomId
FROM Room r2
JOIN r2.appartment a1
WHERE a1.appartmentId = :appartmentId""", Long.class)
.setParameter("appartmentId", appartmentId)
.getResultList();
将其作为参数传递
int updated = entityManager.createQuery(
"""UPDATE Room r1
SET r1.available = :availability
WHERE r1.roomId IN :roomIds""")
.setParameter("availability", availability)
.setParameter("roomIds", roomIdList)
.executeUpdate();