好的,我现在有点纠结了。我读过很多其他相关问题,但这并没有帮助我解决我的问题。如果有人能帮助我,我会很高兴。正确地级联这个@OneToMany关系(Spring数据JPA)
我使用Spring数据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
来“解决”这个问题。现在,当我使用现有的Device实体保存新的Reading时,该设备会正确更新。 但是现在我不能再级联一个还不存在的设备!
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);
我想这个问题的一部分,可能与我做设置分离实体?
我在做什么错?我的身份不好吗?发生什么事?我是否需要手动管理这些交易?
谢谢!
我删除了''cascade''但没有帮助。仍然获得''列'device_id'不能为空''。我也为这个问题增加了保存部分,因为它可能很重要。 – sldk
您是否使用'@ Id'注释定义了主键?此外,如果您正在创建新对象,则保留id值并在更新时使用它们(但在Dao实现中调用'saveOrUpdate'而不是'save') –
是的。 ''@Id @GeneratedValue private int id;''''阅读''。 ''@私有字符串ID;''在''设备''上。 – sldk