【发布时间】:2015-04-17 15:19:29
【问题描述】:
可以使用 EJB 实体 bean 作为 Map 键吗?像这样的:
Map <EntityBean,String> map = new HashMap<>();
我假设由于表中的每一行都将映射到单个实体 bean 对象,所以应该没有任何问题,但是有什么影响吗?我不打算保留地图。
【问题讨论】:
标签: jakarta-ee ejb
可以使用 EJB 实体 bean 作为 Map 键吗?像这样的:
Map <EntityBean,String> map = new HashMap<>();
我假设由于表中的每一行都将映射到单个实体 bean 对象,所以应该没有任何问题,但是有什么影响吗?我不打算保留地图。
【问题讨论】:
标签: jakarta-ee ejb
首先,EntityBean 是一个 EJB 实现接口,而不是客户端编程接口。您永远不应该引用 EntityBean,只有 EJBObject 或 EJBLocalObject。
无论如何,不,HashMap<EJB(Local)Object, ...> 无效,因为根据 EJB 3.2 可选规范第 3.9 节(或早期版本中的类似语言),未定义 EJB(Local)Object 的 hashCode 和 equals:
请注意,Enterprise JavaBeans 架构并未指定 实体对象的“对象相等”(即使用 == 运算符) 参考。使用比较两个对象引用的结果 Java 编程语言 Object.equals(Object obj) 方法是 未指定。对两个对象执行 Object.hashCode() 方法 不保证代表实体对象的引用 产生相同的结果。因此,客户应始终使用 isIdentical 方法判断两个实体对象是否引用 引用同一个实体对象。
通常无法对实体 bean 引用进行散列,因为无法确定其底层身份。根据您在应用程序中所做的限制,您可能可以使用 EJBObject.getPrimaryKey() 或 {entityInterface,primaryKey} 元组作为映射键(对于某些元编程,您可以使用 EJBObject.getEJBMetaData().getRemoteInterfaceClass())。
(您可能想知道为什么 EJB 规范会限制这一点。实体 bean 仅作为本地启动,并且至少对于远程 RMI-IIOP 存根,equals 和 hashCode 将比较存根标识而不是底层对象。这将导致通过不同服务器获得的逻辑相同的实体引用或逻辑相同的实体引用的序列化形式不同的复杂主键的问题。也许理论上 EJB 规范可以提供某种 EJB(Local)Object.getIdentity()已经实现了 hashCode 和 equals,但即便如此,在确定两个实体 bean 是否具有相同的底层“类型”(实现应用程序/bean?后备表?还是什么?)时仍然存在复杂性,但自从实体 bean 编程以来,这主要是一个有争议的问题模型已死;使用 JPA。如果您被实体 bean 困住并且可以在应用程序中做出假设,那么您可以避免这些复杂性/问题并像我一样成功地散列实体 bean 引用如上所述。)
【讨论】:
您想如何使用 EJB 来表示数据库行?据我所知,为此目的有 JPA 实体(用@Entity 注释的类)。 EJB bean 通常为这些实体提供一些服务(如 CRUD 操作或更复杂的东西,您可以阅读服务外观模式)。
【讨论】: