Невозможно получить использование CascadeTypes
У меня есть два класса домена. Ниже приведен примерный набросок занятий.
Company.java
public class Company{
@OneToMany(orphanRemoval="true",cascade=CascadeType.ALL,
mappedBy="company")
private List<Department> departments;
}
Department.java
public class Department{
@ManyToOne(fetch=FetchType.LAZY,cascade=CascadeType.PERSIST)
@JoinColumn(name="company_id")
private Company company
}
JPA @ManyToOne с CascadeType.ALL говорит, что смысл CascadeType.ALL в том, что постоянство будет распространять (каскадировать) все операции EntityManager. (PERSIST, REMOVE, REFRESH, MERGE, DETACH)
для связанных лиц.
Основной метод Test.java
//session started and transaction begin
Company company=new Company();
company.setName("Company");
Department department=new Department();
department.setName("Testing department");
department.setCompany(company);
session.save(department);
//transaction committed and session closed
Это дает мое исключение
Exception in thread "main" org.hibernate.PropertyValueException: not-null property references a null or transient value: someValue
Но когда я использую CascadeType.ALL
на аннотации @ManyToOne, работает нормально, но не с CascadeType.PERSIST
Так что я должен использовать, чтобы этот пример работал без использования CascadeType.ALL
как ВСЕ использует (PERSIST, REMOVE, REFRESH, MERGE, DETACH)
, Итак, что из следующего я должен использовать для выполнения своей работы вместо ВСЕХ и как они работают?
2 ответа
Вы установили CascadeType в PERSIST
в Department
сущность, поэтому вы должны использовать session.persist(Object)
метод вместо save
,
Так что используйте это:
session.persist(department);
Обновить:
Company
для объекта CascadeType установлено значение ALL
на Department
, Также в отношениях один-ко-многим сторона, которая является Department
является владельцем ассоциации.
Так что если вы сохраните Company
вместо Department
CascadeType.ALL
применимо. Поскольку Компания не является владельцем ассоциации, вы должны добавить отдел в свой Company
поддерживать двунаправленные отношения. Код выглядит так.
List<Department> departments = new ArrayList<Department>();
departments.add(department);
company.setDepartments(departments);
session.persist(company); // or you can also use save here.
Если вы не поддерживаете отношения, то Department
не будет сохранен в базе данных.
Кажется, вы смешиваете аннотации JPA с интерфейсом сеанса Hibernate.
Если вы используете интерфейс Hibernate Session, вам следует использовать аннотации Hibernate. То есть:
@Cascade(CascadeType.SAVE_OR_UPDATE)
private Company company
Если вы решите использовать аннотации JPA, вам следует использовать интерфейс EntityManager и вызвать
entityManager.persist(departement);
вместо session.save().
Я предлагаю придерживаться интерфейса JPA и использовать EntityManager.
ОБНОВИТЬ:
Я думаю, что реальная проблема заключается в том, что вы пытаетесь сохранить (или сохранить) неприкрепленную сущность, Департамент, которая связана с другой неприкрепленной сущностью, Компанией, в отношениях Один-ко-многим. Когда это происходит, Hibernate должен проверить, присутствует ли Компания на БД, путем слияния (присоединения) сущности Компании. Поэтому, если вы хотите вставить в БД новую запись для Департамента и еще одну для Компании, вы должны альтернативно:
- перед сохранением департамента вызовите persist (company), чтобы объект Company уже был объединен, и Hibernate не нужно его объединять.
ИЛИ добавить CascadeType.MERGE в компанию
@ManyToOne(cascade={ CascadeType.MERGE, CascadeType.PERSIST })
private Company company