我的要求是使用hibernate映射各种数据库(特别是SQLServer、MySQl和Postgres);从db记录创建一个xml文件。
对于hibernate,我正在使用JAssist在运行时创建hbm文件和POJO。我的代码工作得很好,为了进一步模块化,我为每个数据库实现了片段束。因此,我的主机包将处理运行时类的创建,并将它们添加到classloader、hbm文件创建逻辑和BL中。fragment通过传递参数来调用它。
当我为每个数据库创建一个片段包时,在我的主机包中创建的运行时pojo类在我的片段包中是可见的,我检查了“Thread.current线程(). getContextClassLoader(). loadClass()”并能够创建它的实例,
问题是,当我从片段束调用Hibernate函数时,我得到的是“实体未映射”,如果Hibernate无法找到带有表的映射类,则会出现这些异常。所以我想Hibernate没有找到我的运行时pojo类。它可以在主机中找到。
主机:运行时Pojo创建、HBM和CFG创建和更新逻辑BL
片段:Hibernate层,调用Hibernate函数,XML创建逻辑
Hibernate OSGi目前有几个注意事项,其中一个需要单个持久性单元客户端包。出于各种原因,在构建负责处理持久性实体、映射和资源的类加载器时,我们必须使用“requestingBundle”。
看看:https://github.com/hibernate/hibernate-orm/blob/master/hibernate-osgi/src/main/java/org/hibernate/osgi/OsgiClassLoader.java
当服务被调用时,OsgiPersis ence ProviderService和OsgiSessionFactoryService都将“Request estingBundle”添加到ClassLoader。正如Johanna所建议的,除了请求捆绑包或persistence.xml文件本身的位置之外,没有一种像样的方法可以知道哪些捆绑包构成持久性单元。
然而,我很想听听如何更好地支持这样的设置。我最初在清单中使用了额外的元数据来表示“我是持久性单元x的一部分”,但从来没有真正花时间仔细考虑过。
绝对不要使用上面推荐的使用ClassLoaderHelper的解决方案。这是一个完全临时的hack,将在ORM 5中消失。它的存在纯粹是由于ORM 4的静态特性。
看看org。冬眠内部的util。ClassLoaderHelper。
您所要做的就是用能够解析您的实体类的ClassLoader替换ClassLoader。Hibernate-Osgi还将其设置为OSGI ClassLoader(参见org.hibernate.osgi.HibernateBundleActivator)。因此建议如下:
BundleWideClassLoader cl = new BundleWideClassLoader();
if (ClassLoaderHelper.overridenClassLoader != null
&& ClassLoaderHelper.overridenClassLoader instanceof OsgiClassLoader)
{
OsgiClassLoader ocl = (OsgiClassLoader)ClassLoaderHelper.overridenClassLoader;
for (Bundle b : cl.getBundles()) {
ocl.addBundle(b);
}
} else {
ClassLoaderHelper.overridenClassLoader = new BundleWideClassLoader();
}
我将它放到我的HibernateConfiguration类中,方法是重写BuildSessionFactory,它执行此例程并返回super.buildSessionFactory。
BundleWideClassLoader看起来像这样
public class BundleWideClassLoader extends ClassLoader
{
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
for (BundleClassLoader cl : this.getAllClassLoader()) {
try {
Class clazz = cl.findClass(name);
return clazz;
} catch (Exception ex) {
}
}
throw new ClassNotFoundException(name);
}
@Override
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
Class clazz = this.findClass(name);
if (resolve) {
this.resolveClass(clazz);
}
return clazz;
}
@Override
public URL findResource(String name) {
for (BundleClassLoader cl : this.getAllClassLoader()) {
URL ret = cl.findResource(name);
if (ret != null) {
return ret;
}
}
return null;
}
/**
* Returns a list of all available BundleClassLoader.
*
* @return classloader
*/
public HashSet<BundleClassLoader> getAllClassLoader() {
//
// Do some magic here to get your ClassLoaders from all of your Bundles
//
}
/**
* Returns a list of all bundles which are registered in this BundleWideClassLoader.
*
* @return list of managed bundles
*/
public HashSet<Bundle> getBundles() {
HashSet<Bundle> bundles = new HashSet<>();
for (BundleClassLoader cl : this.getAllClassLoader()) {
bundles.add(cl.getBundleContext().getBundle());
}
return bundles;
}
}
最后是BundleClassLoader:
public class BundleClassLoader extends ClassLoader
{
/**
* Bundle context.
*/
private BundleContext context;
/**
* Constructor.
* @param ctx Bundle Context
*/
public BundleClassLoader(BundleContext ctx) {
this.context = ctx;
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
return this.context.getBundle().loadClass(name);
}
@Override
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
Class clazz = this.findClass(name);
if (resolve) {
this.resolveClass(clazz);
}
return clazz;
}
@Override
public URL findResource(String name) {
return this.context.getBundle().getResource(name);
}
/**
* Returns bundle context.
* @return bundle context
*/
public BundleContext getBundleContext() {
return this.context;
}
}
我建议在每个BundleActivators中创建一个新的BundleClassLoader,并将其添加到某种注册表中,这样BundleWideClassLoader就可以从那里获得BundleClassLoader的列表。当包停止或删除时,不要忘记删除BundleClassLoader。
如果在多个包上使用Hibernate,则总是会出现此问题。在Hibernate配置中,您无法判断映射文件和pojo类文件位于哪个包中。Hibernate不使用OSGI提供的机制。因此,hibernate只能找到与hibernate库位于同一捆绑包中的映射文件和类。
我不知道是否有专业的解决方案(第三方产品)来解决这个问题。
解决这个问题有两种可能性:
>
忘记您的片段包,将所有Hibernate库、映射文件、pojos、所有数据库使用Hibernate/HQL的类放入一个包中。当您使用不同的hibernate.cfg.xml文件时,您可以在不同的数据库之间切换;每个数据库都有自己的配置文件。这些hibernate.cfg.xml文件可以在包之外。
编写您自己的Configuration类,扩展org.hibernate.cfg.Configuration,在这个类中,您必须
我们做了解决方案2。它有点工作量,但现在运行良好。(我想,当再次更改Hibernate版本时,可能需要做一些工作。)
问题内容: 我的要求是使用hibernate映射各种数据库(尤其是SQL Server,MySQl和Postgres);从db记录创建一个xml文件。 对于hibernate,我正在使用JAssist在运行时创建hbm文件和pojos。我的代码很棒,为了进一步模块化,我为每个数据库实现了片段捆绑包,以便我的主机捆绑包可以处理运行时类的创建并将其添加到类加载器,hbm文件创建逻辑和BL中。片段通过传
我正在基于模板进行查看,但在某些区域我想输入片段。 模板:base。html 查看:列表。html 片段:片段/init.html 对于头部碎片,它可以正常工作。但在页脚中,但在页脚中,将显示模板的代码。 输出: 我希望你能帮助我。提前感谢。 使现代化 基础html 列表html init.html 输出: 我设法在页脚中包含代码片段,但我的目标是替换它。 解决方案:
我试图在运行时动态创建POJO类并将它们映射到Hibernate。但是,我在第二部分失败了。 生成类文件后,我将其放置在Hibernate扫描POJO的位置。但它不起作用。 我再次尝试重建会话工厂,以便它可以接收新创建的文件,但这不起作用。重建会话工厂也不是一个好的/可扩展的解决方案。 Hibernate设置代码: 错误:
我正在使用jetpack导航从片段过渡到细节片段。 我需要帮助在显示细节片段的片段上显示细节片段。 请看下面的照片,看看我正在努力实现什么: 我也在导航图中的动画上使用基本的fade_in/fade_out。 这是我得到的结果: 如何设置转换以使细节片段显示在呈现视图上? 这是我所有的进步: 底部导航菜单 导航图 主要活动。kt Tab1片段(这是带有埃菲尔铁塔图像的片段 赏金编辑: 我希望在导航
问题内容: 而不是将数据库操作分散在四个(osgi)包中,所有操作都在这里稍有不同。我想创建一个负责所有持久性问题的(简单)OSGi捆绑包。我觉得这并不像听起来那么简单,因为“每捆都有唯一的类加载器”。因此,如果有人知道这种问题的解决方案,我将非常感激。 问题答案: (如果您正在使用hibernate注释) 在通知Hibernate捆绑包有关注释类的信息后,保存所有Entities类加载器。 然后