Я пытаюсь сохранить в каскаде следующие два объекта JPA (получатели / установщики и другие поля опущены):
@Entity
public class TestEntity {
@Id @GeneratedValue
private Integer id;
private String name; // field only necessary so there is at least one mapping in the table
@ElementCollection
@MapKeyJoinColumn(name="PROPERTY_KEY", referencedColumnName="ID")
@Column(name="PROPERTY_VALUE")
@CollectionTable(name="PROPERTIES")
private Map<TestKey, String> properties = new HashMap<>();
}
@Entity
public class TestKey {
@Id @GeneratedValue
private Integer id;
private String name;
}
Это код, который я использую для сохранения объекта:
EntityManager em = ...
em.getTransaction().begin();
TestKey key = new TestKey();
key.setName("some key");
TestEntity entity = new TestEntity();
entity.getProperties().put(key, "some value");
em.persist(entity);
em.getTransaction().commit();
em.close();
Но когда я это делаю, я получаю следующее исключение:
java .lang.IllegalStateException: во время синхронизации был обнаружен новый объект через отношение, которое не было помечено каскадом PERSIST: TestKey
Я могу это исправить, сохранив ключ перед сохранением сущности следующим образом:
[...]
em.persist(key); // <<-- line added to previous example
em.persist(entity);
em.getTransaction().commit();
em.close();
Этот код работает, как и ожидалось, и сохраняет TestEntity
и TestKey
.
Возможно ли как-то каскадно-сохранить сущность без явного сохранения ключа - возможно, я здесь что-то не так делаю?
Я действительно думал, что все отображения @ElementCollection
автоматически каскадно сохраняются. Я пришел к такому выводу из следующих утверждений:
https://wiki.eclipse.org/EclipseLink/Examples/JPA/2.0/ElementCollections
Это не каскадная опция в ElementCollection, целевые объекты всегда сохраняются, объединены, удалены вместе с их родителями.
{ ссылка }:
Вам не нужна аннотация @ManyToMany здесь. Операции над ElementCollections всегда каскадные.
Я использую EclipsLink
версия 2.5.2.v20140319-9ad6abd
2.7.5.v20191016-ea124dd158
.