JPA сохранить объект в отношениях ManyToOne - PullRequest
6 голосов
/ 27 ноября 2010

У меня есть отношение компании / сотрудника @OneToMany в моей базе данных, определенное как:

@Entity
public class Employee {
   @Id @GeneratedValue(strategy=GenerationType.IDENTITY)
   private long id;
   @ManyToOne @JoinColumn(name="companyid")
   Company company;
   ....
}

@Entity
public class Company {
@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
private long id;

...
}

Теперь я добавляю недавно созданного сотрудника в отдельную компанию.Код, который я использую, выглядит примерно так:

Company company = em1.find(Company.class, 555L);
em1.close();

EntityTransaction et = em2.getTransaction();
et.begin();
Employee employee = new Employee();
employee.company = company;
em2.persist(employee);
et.close();

Будет ли это работать нормально?
Собирается ли Hibernate объединить компанию во 2-й EntityManager или просто использовать ее идентификатор и сохранить объект сотрудника?
Может ли hibernate каким-либо образом дублировать объект моей компании или выдать исключение, говорящее, что компания с таким же идентификатором уже существует в БД?

1 Ответ

8 голосов
/ 27 ноября 2010
  • В описанном случае Company 'id будет использоваться при сохранении объекта Employee, но сам Company не будет объединен (обратите внимание, что Employee является собственной стороной отношения)
  • Если Company является временным, а не отсоединенным, вы получите «объект ссылается на несохраненный временный экземпляр» ошибка
  • Если используется cascade = CascadeType.PERSIST, вы получите «отсоединенный объект, переданный вpersist "error.

Из JPA Спецификация:

Если X является управляемым объектом, он синхронизируется с базой данных.

  • Для всех объектов Y, на которые ссылается отношение из X, если отношение к Y было аннотировано значением каскадного элемента cascade = PERSIST или cascade = ALL, операция постоянства применяется к Y.
  • Для любого объекта Y, на который ссылается отношение из X, где отношение к Y не было аннотировано значением элемента каскада cascade = PERSIST или cascade = ALL:
    • Если Y является новым или удаленным, IllegalStateException будет выдан операцией очистки (и транзакция, отмеченная для отката), или фиксация транзакции завершится неудачей.
    • Если Y отделен, семантика зависит от принадлежности отношений. Если X владеет отношением, любые изменения отношения синхронизируются с базой данных; В противном случае, если Y владеет отношениями, поведение не определено.
...