好吧,我现在有点乖乖。我已经阅读了许多其他相关问题,但这并没有帮助我解决我的问题。如果有人可以帮助我,我会很高兴。
我正在使用Spring Data JPA,我有这两个实体:
Device.class
private String id;
@OneToMany(mappedBy = "device", cascade = CascadeType.ALL)
@JsonIgnore
@RestResource(exported = false)
private List<Reading> readings;
Reading.class
@ManyToOne(cascade = {CascadeType.MERGE}) /*This isn't right...*/
@JoinColumn(name = "device_id")
private Device device;
期望
我只保存读数,并希望设备能够正确级联(持久或合并),具体取决于它是否已存在。 (读数只插入一次,永远不会更新)
现实
我只能将此作品部分:
当我使用cascade = CascadeType.ALL
或cascade = CascadeType.PERSIST
时,我可以保存首先阅读及其映射的设备。一旦我插入了与同一设备有关系的第二个阅读,我就会得到以下内容:
Duplicate entry '457129' for key 'PRIMARY'
('457129' = Reading.Device.id)
据我所知,第二个读取实体尝试通过插入新行而不是更新现有行来级联其设备。
我可以使用cascade = CascadeType.MERGE
代替“解决”这个问题。现在,当我使用现有设备实体保存新读数时,设备会正确更新。 但是现在我再也无法级联一个尚不存在的设备了!
Column 'device_id' cannot be null
(Reading.device_id)
保存
我收到JSON DTO并从中创建实体。
伪代码:
Reading reading = deserialize(jsonReading);
Device device = deserialize(device);
reading.setDevice(device); /* Device entity is detached */
readingService.save(reading);
我想部分问题可能与我设置一个分离的实体有关?
我做错了什么?我的关系不好吗?怎么了?我是否需要手动管理这些交易?
谢谢!
答案 0 :(得分:0)
@OneToMany关联定义为父关联,即使它是单向关联或双向关联。只有关联的父方才有意义将其实体状态转换级联到子级。 (来源:Hibernate docs)。
根据文档,我将从cascade
字段中删除device
。文档还包含用于存储您可能尝试的Phone
和Person
的{{1}}和@OneToMany
的代码示例。
由于您没有发布任何用于保存部分的代码,我认为您在将@ManyToOne
保存为
reading
持久存储reading.setDevice(device);
readingDao.save(reading); // depends on your implementation
对象后,reading
应自动保存。