0

I have a very strange behavior in my program. I have 2 classes (class LogIn and CreateGame) where i have injected an EntityManager in each using the annotation

  @PersistenceContext(unitName="myUnitPU")
  EntityManager entitymanger;

In some point i remove an object called "user" from the database using entitymanger.remove(user) from a method in LogIn class. The business logic is that a user can host and join games ( in the same time) so removing the user all the entries in database about the games the user has created are removed and all the entries showing in which games the user has joined are removed also.

After that, i call another function which checks if the user exists using a method in the LogIn class

  entitymanager.find(user)

which surprisingly enough, finds the user. After that I call a method in CreateGame class which tries to find the user by using again

  entitymanger.find(user) 

the entitymanger in that class fails to find the user (which is the expected result as the user is removed and it's not in the database)

So the question is : Why the entitymanager in one class finds the user (which is wrong) where the other doesn't find it? Does anyone has ever the same problem?

PS : This "bug" occurs when the user has hosted a game which is joined by another user (lets call him Buser) and the Buser has made a game which is joined by the current user.

 GAME  |  HOST  | CLIENTS   
 game1 |  user  | userB
 game2 |  userB | user

where in this case by removing the user, the game1 is deleted and the user is removed from game2 so the result is

 GAME  |  HOST  | CLIENTS   
 game2 |  userB | 

PS2 : The Beans are EJB3.0. The methods are called from a delegate class. The beans in the delegate class are instantiated using the InitialContext.lookup() method. Note that for logging in ,creating , joining games the appropriate delegate class calls the correspondent EJB which does the transactions. In the case of logOut, the delegate calls an EJB to logout the user but becuase other stuff must be done (as said above) this EJB calls other EJB (again using lookup() ) which has methods like removegame(), removeUserFromGame() etc. After those methods are executed the user is then logged out. Maybe it has something to do with the fact the the first entity manager is called by a delegate but the second from inside an EJb and thats why the one entitymanger can see the non-existent user while the other cannot? Also all the methods have TRANSACTIONTYPE.REQUIRED

Thank you in advance

C.LS
  • 1,319
  • 2
  • 17
  • 35
  • 1
    You description is unclear. Are these classes EJB 3.0 beans? How do you call their methods? Also `@PersistenceUnit` cannot inject `EntityManager`. – axtavt Dec 20 '10 at 17:51
  • added the PS2 to clarify some points. Thank you for the comment – C.LS Dec 21 '10 at 11:53
  • Are you using stateful or statless ejbs? If stateful, are you also using extended peristence context? If so, are you explicitly committing the transaction? – Sami Korhonen Sep 20 '13 at 21:45

2 Answers2

1

I suppose the the user object is detached and is out of sync with the database. So it is taken from cache. You are not using the extended persistence context within a stateful session bean. So the entity is only managed within a transaction by the entity manager. Try to search the user with its PK Id.

  • not sure if this the correct asnwer to this problem, 2 years after, i don't even have this snippet of code. But i have stumbled upon analogous situations and indeed the problem was the "caching". So I mark your answer as corrent. to summurise : Turn the jpa caching "off" and the entity will not be found in any case. The caching option is enabled/disabled in Persistence.xml (i.e in eclipse link use : to turn it off ) – C.LS Oct 03 '13 at 13:01
0

Most probably, user deletion transaction has not been committed while that user has been queried. therefore, I would suggest you to check the transactions. And also, querying that user should be a different transaction, if both operations were in the same transaction, entity manager would not find the deleted user.

Gursel Koca
  • 20,940
  • 2
  • 24
  • 34
  • The deletion transaction is committed (at least in the database where the user does not exist anymore). More over the deletion of the user and the creation of game are indeed in different transactions. Specifically after logging out , i press the "log in" button which calls a delegate which calls the EJB to log the user in. If the user is already in DB it proceeds , if he is not.. it creates one and proceeds (i am redirected to another page). Then i press "createGame" button which fails because there is no user in the DB. – C.LS Dec 21 '10 at 12:45
  • which jpa implementation are u using?.. and also coould u post the entity classes and the deletion and querying code.. – Gursel Koca Dec 21 '10 at 14:06