一尘不染

带有运行时pojos的Hibernate的OSGi Fragment捆绑软件

hibernate

我的要求是使用hibernate映射各种数据库(尤其是SQL Server,MySQl和Postgres);从db记录创建一个xml文件。

对于hibernate,我正在使用JAssist在运行时创建hbm文件和pojos。我的代码很棒,为了进一步模块化,我为每个数据库实现了片段捆绑包,以便我的主机捆绑包可以处理运行时类的创建并将其添加到类加载器,hbm文件创建逻辑和BL中。片段通过传递参数来调用它。

当我为每个数据库创建一个片段束时,在我的片段束中可以看到在主机束中创建的运行时pojo类,我使用“
Thread.currentThread()。getContextClassLoader()。loadClass()”进行了检查并能够创建其实例,

问题是,当我从片段捆绑中调用Hibernate函数时,我收到“未映射实体”,AFAIK当hibernate无法找到具有表的映射类时,将出现这些异常。所以我猜Hibernate没有找到我的运行时pojo类。它可以在主机中找到。

主机:运行时Pojo创建,HBM和CFG创建以及更新逻辑BL

片段:Hibernate层,调用Hibernate函数,XML创建逻辑


阅读 270

收藏
2020-06-20

共1个答案

一尘不染

如果您在多个捆绑包中使用了Hibernate,则始终会出现此问题。在Hibernate配置中,您无法确定可以在哪个Bundle中找到映射文件和pojo类文件。Hibernate不使用OSGI为此提供的机制。结果,hibernate仅查找与Hibernate库位于同一包中的映射文件和类。

我不知道是否存在针对此问题的专业解决方案(第三方产品)。

有两种方法可以解决此问题:

  1. 忘记片段捆绑包,并将所有数据库的使用Hibernate / HQL的所有Hibernate库,映射文件,pojos,类放入单个捆绑包中。当您使用不同的hibernate.cfg.xml文件时,可以在不同的数据库之间进行切换。每个数据库都有其自己的配置文件。这些hibernate.cfg.xml文件可以位于捆绑软件之外。

  2. 编写扩展org.hibernate.cfg.Configuration的您自己的Configuration类,在该类中,您必须

    • 编写自己的类加载器,即使在其他包中也可以找到pojo类
    • 覆盖addResource(String resourceName,ClassLoader classLoader)的方式也可以在其他包中查找资源
    • 覆盖doConfigure和buildSessionFactory,以便它们使用您的类加载器而不是标准类加载器(使用Thread.setContextClassLoader并从超类(即从标准Hibernate Configuration类)调用该方法)。
    • 覆盖所有其他其他返回Configuration实例的方法,以便它们返回Configuration类而不是Hibernate Configuration类的实例。

我们做了解决方案2。这虽然有点工作,但是现在运行良好。(以为,当再次更改Hibernate版本时,可能需要做一些工作。)

2020-06-20