3

I have an java.persistence.Entity class, that I instantiate and persist using java.persistence.EntityManager.persist. For safety I make sure it's merged into the persistence context and I'm good.

Now, I know that when I create the entity from scratch, I need to manually persist it via the EntityManager, but what about if I simply retrieved an already existing record as an entity? My testing indicates that simply calling setters on that entity results in the updates making it to the database, but I'm looking for something definitive to rely on. So please can anyone shed light or a source on when (reliably) do updates to an attached entity get written disk. At this point, I've no choice but to manually persist the entity after making my changes but I rather know when and when I don't have to.

Update:(thanks Yusuf) according to the accepted answer mentioned below, my question is answered. JPA EntityManager: Why use persist() over merge()?.

According to that answer persist itself does nothing other than add the entity to the persistence context. And merge adds a new object to the context. The implication then is that persistence is simply a function of being part of the persistence context, and since by getting hold of an entity via the entity manager, the entity is attached to the context, so it follows that there is no need at all to call persist.

Community
  • 1
  • 1
naftalimich
  • 401
  • 4
  • 13

2 Answers2

2

As you said, you need to call persist if you create an object from scratch.

If you access a JPA Entity using an EntityManager, you never need to call persist method because when transaction ends(most of time it is on returning the transactional method), it persists automatically. If you do not want to persist automatically when transactional method returning, you have to use detach method of EntityManager.

Also this answer may give you more information

Community
  • 1
  • 1
Yusuf K.
  • 4,195
  • 1
  • 33
  • 69
  • My transactional attribute is defined on the interface implementation @Local that contains an injected entitymanager and persists and finds entities. so actions via those methods r persistent since by definition executing within a transaction. My question is when I get hold of an entity object via this interface, via the entity manager, and the transaction, say on a call to find, is over, so now I have in my client a reference to my entity which is a pojo. I call a setter on that object directly, without any entity manager mediation, when and when not do I need to manualy persist my entity. – naftalimich Feb 25 '16 at 20:57
  • When using @TransactionAttribute annotation on a class, this means all methods are effected by this annotation. After this EJB bean's method returns, the pojo goes out of context and changes not send database anymore. – Yusuf K. Feb 25 '16 at 21:03
  • Not sure about that because my testing indicates that at least some of the times my updates to my pojo obtained via the EJB do automatically make it to the database. In any case I've certainly been coding according to your presumption. – naftalimich Feb 25 '16 at 21:11
  • Take test step by step and maybe trying example on http://stackoverflow.com/a/1070629/517134 give you some idea – Yusuf K. Feb 25 '16 at 22:06
1

One of the use cases in which you might call EntityManager.persist on a managed entity instance is when you associate transient instances with it and you need ids of those instances before flushing.

Suppose you have the following model:

@Entity
public class A {
    @ManyToOne(cascade = CascadeType.PERSIST)
    private B b;

    @ManyToOne(cascade = CascadeType.PERSIST)
    private C c;
}

Then you associate A with new instances of B and C:

A a = entityManager.find(...);

B b = new B();
a.setB(b);

C c = new C();
a.setC(c);

Now, if you need ids of b and c, you would need to persist both of them explicitly, or you could just persist a since PERSIST operation will be cascaded (this is especially suitable for larger and more complicated object graphs):

entityManager.persist(a);
Dragan Bozanovic
  • 23,102
  • 5
  • 43
  • 110