2

As the title suggests, I'm using Apache Struts2 with JPA Eclipselink on my web application. Let's say that I have a couple of edit options there, in which most of them span only a single action and a single JSP page. In that cases that the approach I'm doing is the obvious one:

EntityManagerFactory emfactory = Persistence.createEntityManagerFactory( "Eclipselink_JPA" );
EntityManager em = emfactory.createEntityManager();
em.getTransaction().begin();
Entity entity = em.find( Entity.class, this.id );

entity.setName("Test");

entitymanager.getTransaction().commit();
entitymanager.close();
emfactory.close();

However, there is a more complex edit option that spans accross 4 different JSP pages (and even more actions). The approach I'm using is to store both the EntityManager and EntityTransaction objects in the session object (on the first edit action), and then retrieve it back in the last one, to finish the transactions. Something like this:

1. First edit action:

EntityManagerFactory emfactory = Persistence.createEntityManagerFactory( "Eclipselink_JPA" );
em = emfactory.createEntityManager();
et = em.getTransaction();
et.begin();

this.session.put("em", em);
this.session.put("et", et);

2. Last edit action:

em = (EntityManager) session.get("em");
et = (EntityTransaction) session.get("et");

entity.setName("Test");

et.commit();
em.close();

So, my question is: is this approach recommended? It seems to be working ok, but maybe there is a better, more reliable solution out there that I'm not aware of. What are your thoughts on this?

Roman C
  • 49,761
  • 33
  • 66
  • 176
João Fernandes
  • 558
  • 3
  • 11
  • 29
  • 1
    Don't store it in session, IMHO, better use session management tools. – Roman C May 16 '15 at 08:44
  • Can you elaborate on that? After a quick search on the topic, I can only conclude that you're probably referring to interceptors, am I right? How could I achieve it that way? – João Fernandes May 17 '15 at 14:34
  • You said you store them in session and it works for you, what else do you want? Better or not better is primarily opinion based and off-topic here, if you have a specific question edit your post there. – Roman C May 17 '15 at 20:39
  • As we all know "it works" doesn't mean it's a recommended, elegant (and even) secure solution. Since you referred an alternative on your first comment, I was hoping you could expand on that, since I couldn't figured it out by myself. – João Fernandes May 21 '15 at 10:51

1 Answers1

1

I think storing a transaction opened for quite a long time, it's not a good idea.

I would store only the entity in the session and do the whole transaction after the last step.

Or persist your data after each step, but each in a separate transaction.

zsom
  • 479
  • 1
  • 5
  • 19
  • Thank you so much, I needed this answer to have a click and *fully* realize that I don't have to start the transaction *before* making changes to the entity's instance. – João Fernandes May 21 '15 at 13:41
  • I take it back: It only works when I use the same `EntityTransaction` object to call `begin()` and `commit()`, and so I have to store it somewhere and somehow pass it to the last action, where `commit()` is being called. – João Fernandes May 25 '15 at 15:37