JPA:EntityManager.find() 是否总是为相同的键返回相同的对象引用?
我对 DAO 进行了集成测试,其中使用共享 EntityManager(通过 Spring,使用 SharedEntityManagerCreator)。测试类被标记为 @Transactional,被测试的 DAO 方法也是如此。
在测试类和 DAO 中,我按如下方式检索用户实体:
User user = em.find(User.class, "test");
在测试设置中,我修改了用户对象,但当测试运行时,我没有在 DAO 中看到修改。事实证明,这两个引用并没有引用同一个对象;我在我的测试类中使用以下方法证明了这一点:
System.out.println("User objects equal = " + (user == dao.getUser()));
这打印出错误。我希望每次使用相同的键调用 EntityManager 都会返回相同的对象引用,并且很惊讶(并且有点惊慌!)发现情况并非如此。任何人都可以阐明这一点吗?我已经重构了我的代码,所以这实际上不是一个问题(DAO 无论如何都不应该有 User 对象),但我仍然想更好地理解这一点。
谢谢!
Java 1.6u22、Toplink Essentials 2.0.1、Spring 2.5.6
I've got an integration test of a DAO in which I use a shared EntityManager (via Spring, using SharedEntityManagerCreator). The test class is marked as @Transactional, as is the DAO method under test.
In both the test class and the DAO I'm retreiving a User entity as follows:
User user = em.find(User.class, "test");
In the setup of my test I've modified the user object, but I wasn't seeing the modification in the DAO when the test came to run. It turned out that the two references did not refer to the same object; I proved this in my test class using:
System.out.println("User objects equal = " + (user == dao.getUser()));
This printed out false. I would expect that every call to an EntityManager using the same key would return the same object reference, and was surprised (and a bit alarmed!) to find out this was not the case. Can anyone shed any light on this? I've refactored my code so it's not actually an issue (the DAO shouldn't have had the User object in it anyway) but I'd still like to understand this better.
Thanks!
Java 1.6u22, Toplink Essentials 2.0.1, Spring 2.5.6
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
find()
返回持久化上下文范围内的相同实例。在共享 EntityManager(容器管理的事务范围持久化上下文,JPA 规范术语中)的情况下,持久化上下文的生命周期绑定到事务,因此 find() 返回从同一事务调用时的同一实例。
我想在您的情况下,您的测试设置不会在与测试方法相同的事务中发生,因此find()
会生成不同的实例。find()
returns the same instance inside a scope of persistence context.In the case of shared
EntityManager
(container-managed transaction-scoped persistence context, in JPA Spec terms) lifecycle of persistence context is bound to the transaction, thereforefind()
returns the same instance when called from the same transaction.I guess in your case setup of your test doesn't happen in the same transaction as a test method, sofind()
produces different instances.不,事实并非如此。无论如何,您应该依赖对象 EQUALITY 而不是 IDENTITY。重写 equals 方法。
No it does not. You should rely on object EQUALITY instead of IDENTITY anyway. Override the equals method.