2

I am using Servlet->EJB->JPA on Glassfish 4. Application deploys successfully.

When I run the servlet, it updates the entity with id=1 in db, but doesn't do anything for the one with id=2. No exception is thrown.

@WebServlet("/AnimalServlet")
public class AnimalServlet extends HttpServlet {

@EJB AnimalDAOLocal lOBAnimalDAO;

protected void doGet(....) {
    Animal lOBAnimal = lOBAnimalDAO.getAnimal(1); // gets OK
    lOBAnimal.setName("Animal1");  // sets OK
    lOBAnimalDAO.mergeAnimal(lOBAnimal); // updates in DB OK
    lOBAnimal = lOBAnimalDAO.getAnimal(2); // gets OK
    lOBAnimal.setName("Animal2"); // sets OK
    lOBAnimalDAO.mergeAnimal(lOBAnimal); // doesn't update in DB.
}

And Session Bean Methods are :

@Stateless(mappedName = "AnimalDAOMapped")
public class AnimalDAO implements AnimalDAOLocal {
    @PersistenceContext EntityManager em;

    public Animal getAnimal(int id) {
          return em.find(Animal.class, id);
    }

    public void mergeAnimal(Animal pOBAnimal) {
          em.merge(pOBAnimal);
    }
}

Persistence Unit Settings :

<persistence-unit name="JPATest" transaction-type="JTA">
    <jta-data-source>jdbc/animaltest</jta-data-source>
    <class>net.test.model.Animal</class>
</persistence-unit>
Half Diminished
  • 193
  • 1
  • 11
  • No this is not a transaction problem, first entity's name (Animal1) commits successfully. – Half Diminished Jan 21 '14 at 07:19
  • 1
    [This might help you](http://stackoverflow.com/questions/1069992/jpa-entitymanager-why-use-persist-over-merge) – Samy Jan 21 '14 at 08:15
  • Could you paste your persistence context settings? – Jakub Kubrynski Jan 21 '14 at 08:24
  • 1
    Something needs to commit the transaction which you aren't showing. Try adding em.flush to the merge or show more info such as how you are hooking it into a transaction, and turn logging on to see what is happening – Chris Jan 21 '14 at 12:43
  • I didn't annotate the EJB methods to use the default transaction type ( REQUIRED ). The problem should not be related with transaction as the first merge method that I call does the update in database. I will try to add flush just after merge, but this doesn't change the fact that my first merge method commits successfully which is using same "merge" without flush. – Half Diminished Jan 21 '14 at 15:19
  • 1
    Suggesting flush wasn't to resolve the issue, but to see if the EM is associated to a transaction. It will throw an exception if it isn't. The changes will only be picked up if the em is joined to a transaction and that transaction commits, so it is important to show how this is done. Turn on EclipseLink logging to see what it is doing and when, as this might help you see what is different in the two calls. – Chris Jan 21 '14 at 16:05
  • I put the em.flush() method, but result is same there is no exception, it updates for the id=1 but not for the id=2 – Half Diminished Jan 23 '14 at 19:07
  • @Samy your link seemed very close to my solution, but actually at the end I can't still understand the reason – Half Diminished Jan 23 '14 at 19:18

2 Answers2

0

Use flush(); method, throw PersistenceException.Servlet catch that exception.

public void mergeAnimal(Animal pOBAnimal) throws PersistenceException {
    try {
        em.merge(pOBAnimal);
        em.flush();
    } catch (PersistenceException pe) {
        throw e;
    }
}
Zaw Than oo
  • 9,651
  • 13
  • 83
  • 131
0

I solved the problem with the help of Chris' suggestion to turn on EclipseLink Logging ( Which I didn't know before ) .

The problem happened because of wrong @JoinColumn definition in the entity. And the first entity ( db=1 ) was committing by chance because of the existance of dummy data for this id which doesn't exist for other ids.

Half Diminished
  • 193
  • 1
  • 11