Хорошо, я сейчас немного отступил. Я прочитал многие другие связанные вопросы, но это еще не помогло мне решить мою проблему. Буду рад, если кто-нибудь сможет мне помочь.Правильно каскадируйте это отношение @OneToMany (Spring Data JPA)
Я использую 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;
Expectation
Я только экономия Readings и ожидать устройства быть каскадно правильно (сохраняется или объединены), в зависимости от того, существует ли он. (Показания только вставлены один раз, они никогда не обновляются)
Reality
Я могу только сделать эту работу частично:
Когда я использую cascade = CascadeType.ALL
или cascade = CascadeType.PERSIST
я могу сохранить первый Чтение и его отображаемое устройство. После того как я ввожу второе чтение, которое имеет отношение к одному устройству, я получаю что-то вдоль линий:
Duplicate entry '457129' for key 'PRIMARY'
('457129' = Reading.Device.id)
Как я понимаю, второе чтение объект пытается каскад своего устройства, вставив новую строку вместо обновление существующего.
Я могу «обойти» это, используя вместо этого cascade = CascadeType.MERGE
. Теперь устройство обновляется правильно, когда я сохраняю новое Чтение с существующим объектом устройства. BUT теперь я больше не могу каскадировать устройство, которого еще нет!
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);
Я думаю часть проблемы, возможно, придется делать со мной устанавливая отдельностоящий сущность?
Что я делаю неправильно? Я плохо разбираюсь в своих действиях? Что происходит? Мне нужно управлять этими транзакциями вручную?
Спасибо!
Я удалил '' каскад'', но это не помогло. По-прежнему получение '' Column 'device_id' не может быть пустым ''. Я также добавил сохраненную часть к вопросу, поскольку это может быть важно. – sldk
У вас есть первичные ключи, определенные с помощью аннотации '@ Id'? Кроме того, если вы создаете новые объекты, оставьте значения id и используйте их при обновлении (но вызовите 'saveOrUpdate' в реализации Dao вместо' save') –
Да. '' @Id @GeneratedValue private int id; '' '' Чтение''. '' @Id private String id; '' '' Устройство''. – sldk