I was trying to get simple webapp working with Guice and JPA on Jetty, using the persistence and servlet guice extensions.
I have written this Service implementation class:
public class PersonServiceImpl implements PersonService {
private EntityManager em;
@Inject
public PersonServiceImpl(EntityManager em) {
this.em = em;
}
@Override
@Transactional
public void savePerson(Person p) {
em.persist(p);
}
@Override
public Person findPerson(long id) {
return em.find(Person.class, id);
}
@Override
@Transactional
public void deletePerson(Person p) {
em.remove(p);
}
}
And this is my servlet (annotated with @Singleton):
@Inject
PersonService personService;
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String name = req.getParameter("name");
String password = req.getParameter("password");
String email = req.getParameter("email");
int age = Integer.valueOf(req.getParameter("age"));
Person p = new Person();
p.setAge(age);
p.setName(name);
p.setEmail(email);
p.setPassword(password.toCharArray());
logger.info("saving person");
personService.savePerson(p);
logger.info("saved person");
logger.info("extracting person");
Person person = personService.findPerson(p.getId());
resp.getWriter().print("Hello " + person.getName());
}
When I run this it works, and I get the name sent to the client, but when I look at the log I see that there is no DML generated for the insertion and selection from postgresql does not return any results, which means it wasn't really persisted.
I debugged through the code and I saw that JpaLocalTxnInterceptor
called txn.commit()
.
Then I made a change to PersonServiceImpl
and used Provider<EntityManager>
instead of just EntityManager
and it worked as expected. Now I don't really understand why and it's probably because I don't really understand the idea behind Provider.
On the Guice wiki page it says:
Note that if you make MyService a @Singleton, then you should inject Provider instead.
However, my PersonServiceImpl is not a @Singleton so I am not sure why it applies, perhaps it's because of the Servlet?
I would really appreciate if you could clear this out for me.