【问题标题】:can there be multiple instances of the same (Open)JPA entity in an application? Equals does not work for Entity Instances?一个应用程序中可以有多个相同(开放)JPA 实体的实例吗? Equals 不适用于实体实例?
【发布时间】:2012-11-13 14:54:45
【问题描述】:

我们的堆栈:Tomcat 7、Spring 3.1.1、OpenJPA 2.2.0

我遇到了一个问题,根源是比较:

server1.equals(server2);

server1 和 server2 都是实体“服务器”的实例:

@Entity
public class Server implements Serializable {
   private long id;
   // getters and setters
}

我不得不将比较更改为:

server1.getId().equals(server2.getId());

那个有效,上面那个返回false,即使服务器的id是一样的。 我还检查了两个实例的 hashCodes,这两个实例确实有不同的 hashCode。

为什么我们的应用程序中有两个相同实体的实例?

怎么会这样?数据库中只有一个“服务器”实体。

谢谢!
塞巴斯蒂安

【问题讨论】:

标签: java spring jpa entity openjpa


【解决方案1】:

如果它是不同的会话或外部会话,您将拥有多个Entiry 实例。在您的情况下,您正在ClientListHashMapStore 中进行比较,这不是事务的一部分。这意味着没有会话,您将拥有多个实体实例。如果需要比较两个实例,理想情况下应该覆盖equals 方法。

【讨论】:

    【解决方案2】:

    例如,如果您使用不同的实体管理器或不同的事务加载它们,将会有不同的实例。

    【讨论】:

    • 顺便说一句:看看:onjava.com/pub/a/onjava/2006/09/13/…
    • EntityManager 只有一个。也只有一个 ServerDao 被注释为@Transactional。
    • @seba.wagner:我不完全理解您的 ClientListHashMapStore 实现,但如果只有 DAO 有 @Transaction 注释(并且您没有使用 OpenEntityManagerInView 过滤器),如果您调用两个事务,那么您有两个事务不同的道法!
    【解决方案3】:

    首先想到的是您的应用程序中有 2 个(至少)类加载器。一个加载实体,然后创建实例 server1,第二个加载 server2。通常这些由您的技术堆栈在内部管理

    这在 java 中通常是正确的,而不仅仅是在您的特定应用程序中。 现在棘手的部分是这些类加载器是从哪里来的。

    首先,为了确保是这种情况,您可以尝试打印出类加载器,如下所示:

    print before comparison: server1.getClass().getClassLoader()
    print before comparison: server2.getClass().getClassLoader()
    

    这可以让您了解那里发生了什么。 例如,它可能来自不同的部署单位。

    希望对你有帮助

    【讨论】:

      猜你喜欢
      • 2020-09-14
      • 2019-02-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-19
      相关资源
      最近更新 更多