一个entityManger找到entity,另一个没有
我的程序中有一个非常奇怪的行为。我有 2 个类(LogIn 类和 CreateGame 类),其中我使用注释在每个类中注入了一个 EntityManager
@PersistenceContext(unitName="myUnitPU")
EntityManager entitymanger;
在某些时候,我从 LogIn 类中的方法中使用entitymanger.remove(user) 从数据库中删除了一个名为“user”的对象。业务逻辑是用户可以(同时)主持和加入游戏,因此删除用户后,数据库中有关用户创建的游戏的所有条目都将被删除,并且显示用户已加入的游戏的所有条目都将被删除还。
之后,我调用另一个函数,该函数使用 LogIn 类中的方法检查用户是否存在
entitymanager.find(user)
,令人惊讶的是,它找到了用户。之后,我调用 CreateGame 类中的一个方法,该方法尝试再次使用
entitymanger.find(user)
该类中的实体管理器来查找用户,但找不到用户(这是预期结果,因为用户被删除并且不在数据库中)
所以问题是:为什么一个类中的实体管理器找到用户(这是错误的),而另一个类却找不到用户? 有人遇到过同样的问题吗?
PS:当用户主持了一个由另一个用户(我们称他为 Buser)加入的游戏,并且该 Buser 制作了一个由当前用户加入的游戏时,就会出现此“错误”。
GAME | HOST | CLIENTS
game1 | user | userB
game2 | userB | user
在这种情况下,通过删除用户,游戏 1 被删除,用户从游戏 2 中删除 所以结果是
GAME | HOST | CLIENTS
game2 | userB |
PS2 : Bean 是 EJB3.0。这些方法是从委托类调用的。委托类中的 bean 是使用 InitialContext.lookup() 方法实例化的。 请注意,为了登录、创建、加入游戏,适当的委托类会调用执行事务的相应 EJB。在 logOut 的情况下,委托调用 EJB 来注销用户,但由于必须执行其他操作(如上所述),因此该 EJB 调用其他 EJB(再次使用 Lookup() ),该 EJB 具有诸如 removegame()、removeUserFromGame() 之类的方法等。执行这些方法后,用户就会注销。也许这与第一个实体管理器由委托调用但第二个实体管理器从 EJb 内部调用这一事实有关,这就是为什么一个实体管理器可以看到不存在的用户而另一个实体管理器不能看到?另外所有方法都有 TRANSACTIONTYPE.REQUIRED
提前谢谢您
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我认为用户对象已分离并且与数据库不同步。所以它是从缓存中获取的。您没有在有状态会话 bean 中使用扩展持久性上下文。因此实体仅由实体管理器在事务内进行管理。尝试使用 PK Id 搜索用户。
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.
最有可能的是,在查询该用户时尚未提交用户删除事务。因此,我建议您检查交易。而且,查询该用户应该是不同的事务,如果两个操作都在同一个事务中,实体管理器将找不到已删除的用户。
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.