我正在开发一个使用JPA2处理某些数据库实体的工具,其中hibernate作为持久性提供程序。该工具是通用的,并且与任何业务逻辑分离,它需要一个通用的Class<? extends Task>
参数来完成其业务,其中Task是我创建的一个接口,表示实现实体对我的工具有一些有趣的行为。该工具的工作包括从数据库中获取给定类的实例并操纵它们的一些属性。它是一个通用工具,因为它被开发为可重用的,并且我们有一大组实体类(但不是所有实体类)实现了该接口(主要是那些为某些类型的正在运行的业务任务建模的实体)。 p>
要完成工具的工作,我需要为给定的类获得EntityManager
。要获得EntityManager
,我需要一个EntityManagerFactory
。要获得EntityManagerFactory
,我需要持久性单元名称。
所以,我的问题是给定一个实体类,获取其持久性单元的名称。但是,如果没有已经存在的持久性单元的EntityManager,我就没有找到任何方法来实现这一点,这会创建一个鸡蛋或鸡蛋优先,锁定在胸部内部的问题。
部分解决方案是将持久性单元的名称与实体类一起传递,但这看起来是错误的,因为应该从给定的类中推断(或至少猜测)持久性单元的名称。这可以优化为将名称放在实体类的注释中,但这看起来仍然是一个不正确的解决方案。搜索和分析persistence.xml
文件是我们真正想要避免的。
那么,我该怎么做才能解决这个问题呢?有什么想法吗?
答案 0 :(得分:2)
我很确定无法确定实体类与之关联的持久性单元,因为JPA的设计是另一种方式:通常您为特定的持久性单元注入一个EntityManagerFactory。
如果您至少拥有所有可用持久性单位的名称,则可以使用Persistence.createEntityManagerFactory(persistenceUnitName)
创建所有可用工厂,然后使用其元模型检查某个类是否属于某个单元:
for (EntityManagerFactory emf : factories) {
try {
EntityType<?> entity = emf.getMetamodel().entity(classToCheck);
// bingo
} catch (Exception e) {
// wrong persistence unit
}
}
或者您检查MetaModel.getEntities()并构建单元名称到托管实体类的映射。
答案 1 :(得分:0)
关于特定持久性单元中实体关系的静态信息的唯一来源是persistence.xml文件,前提是您在那里声明了实体类,因为您可以省略它们并让持久性管理器全部找到它们你。
也许你可以组织你的代码,以便明确给定类所属的持久性单元。例如,您可以组织每个持久性单元的包,或者您可以使用给定类所属的持久性单元创建自定义Java注释,然后在运行时读取注释。
听起来怎么样?
这些想法只是一种使用不同的静态策略复制persistence.xml应该知道的方法。