Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JPA persist object in a ManyToOne relationship

I have a company/employee @OneToMany relation in my database defined as:

@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;

...
}

Now I am adding a newly created employee to a detached company. The code I use is something like:

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();

Will this work ok?
Is hibernate going to merge the company into the 2nd EntityManager or just use its id and persist the employee object?
Might hibernate somehow duplicate my company object or throw an exception saying that a company with the same id already exists in the DB?

like image 333
tal Avatar asked Nov 27 '10 06:11

tal


1 Answers

  • In the described case Company's id will be used when persisting Employee object, but Company itself will not be merged (note that Employee is the owning side of the relationship)
  • If Company is transient rather than detached, you will get "object references an unsaved transient instance" error
  • If cascade = CascadeType.PERSIST is used, you will get "detached entity passed to persist" error.

From JPA Specification:

If X is a managed entity, it is synchronized to the database.

  • For all entities Y referenced by a relationship from X, if the relationship to Y has been annotated with the cascade element value cascade=PERSIST or cascade= ALL, the persist operation is applied to Y.
  • For any entity Y referenced by a relationship from X, where the relationship to Y has not been annotated with the cascade element value cascade=PERSIST or cascade= ALL:
    • If Y is new or removed, an IllegalStateException will be thrown by the flush operation (and the transaction marked for rollback) or the transaction commit will fail.
    • If Y is detached, the semantics depend upon the ownership of the relationship. If X owns the relationship, any changes to the relationship are synchronized with the database; otherwise, if Y owns the relationships, the behavior is undefined.
like image 153
axtavt Avatar answered Sep 28 '22 06:09

axtavt