提问人:6006604 提问时间:11/17/2023 最后编辑:6006604 更新时间:11/17/2023 访问量:32
尝试使用 JoinTable 清除 OneToOne 关系时违反外键约束
foreign key constraint violation when trying to clear a OneToOne relationship using a JoinTable
问:
我有以下两个实体:
@Entity
public class RoomEntity {
@OneToOne
@JoinTable(
name = "room_camera_association",
joinColumns = {@JoinColumn(name = "room_id")},
inverseJoinColumns = {@JoinColumn(name = "camera_id")}
)
private CameraEntity camera;
...和:
@Entity
public class CameraEntity {
@OneToOne(mappedBy = "camera")
private RoomEntity room;
...关联表的定义如下:
CREATE TABLE room_camera_association
(
camera_id UUID NOT NULL,
room_id UUID NOT NULL,
PRIMARY KEY (camera_id, room_id),
CONSTRAINT fk_camera FOREIGN KEY (camera_id) REFERENCES camera(id),
CONSTRAINT fk_room FOREIGN KEY (room_id) REFERENCES room(id),
CONSTRAINT uk_rca_camera_room UNIQUE (camera_id, room_id)
);
当我删除房间时,我不想删除相机。同样,如果我删除摄像机,我不想删除房间。
当我执行以下代码时:
for (RoomEntity room: getRooms()) {
CameraEntity camera = room.getCamera();
if (camera != null) {
log.info("Removing camera {} association for room {}", camera.getName(), room.getName());
room.setCamera(null);
camera.setRoom(null);
roomRepository.save(room);
cameraRepository.save(camera);
}
...然后执行以下操作:
roomRepository.delete(room);
...我收到以下异常:
2023-11-16 12:50:10.959 ERROR 1641464 --- [ main] o.h.engine.jdbc.spi.SqlExceptionHelper : ERROR: update or delete on table "room" violates foreign key constraint "fk_room" on table "room_camera_association"
Detail: Key (id)=(385a510c-bd26-4f89-8077-6e6b9aa78e31) is still referenced from table "room_camera_association".
我错过了什么?
答:
0赞
Shubham Bansal
11/17/2023
#1
发生这种情况是因为您指定了 (cascade = {CascadeType.ALL})。
尝试将其更改为(cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH, CascadeType.DETACH})
这是因为您不希望 CascadeType.REMOVE 生效。
在移除空间之前,还可以尝试通过以下方式移除room_camera_association -entityManager.createNativeQuery("DELETE FROM room_camera_association WHERE room_id = :roomId").setParameter("roomId", room.getId()).executeUpdate(); roomRepository.delete(room);
评论
0赞
6006604
11/17/2023
实际上,它是在没有级联的情况下发生的。那是在我的帖子中无意中。我已经删除了它。但我没有尝试过 REFRESH 和 DETACH。让我试试。
0赞
6006604
11/17/2023
我收到同样的错误。
0赞
Shubham Bansal
11/17/2023
好吧,这种情况正在发生,因为room_id和camera_id仍然存在room_camera_association。因此,在删除房间或摄像头之前,您必须通过执行以下操作来删除room_camera_association - entityManager.createNativeQuery(“DELETE FROM room_camera_association WHERE room_id = :roomId”).setParameter(“roomId”, room.getId()).executeUpdate();roomRepository.delete(房间);
0赞
6006604
11/17/2023
JPA 不应该处理从@JoinTable中删除数据吗?
0赞
Shubham Bansal
11/17/2023
缺省情况下,JPA 不管理联接表上的关联。在这种情况下,该关系由 RoomEntity 和 CameraEntity 拥有。此外,级联不会删除手动管理的联接表,就像您的情况一样room_camera_association
0赞
6006604
11/17/2023
#2
我弄清楚发生了什么。我们还设置了触发器来审核正在修改或删除的数据。触发功能的设置如下:
INSERT INTO camera_association_log
VALUES (NEW.*, 'DELETE'); RETURN NEW;
...触发因素是.BEFORE DELETE ON
这有效地防止了删除的发生,但这是悄无声息地发生的。当我将函数切换到 并将触发器切换到 时,此代码开始工作:RETURN OLD
RETURN OLD
room.setCamera(null);
camera.setRoom(null);
roomRepository.save(room);
cameraRepository.save(camera);
...自动从关联表中删除记录,并允许后续文件室删除工作。
评论