将Hibernate与动态Eclipse插件配合使用

时间:2023-01-12 15:40:55

I have classes that are named exactly the same across different plug-ins that I use for my application, and I'd like to be able to configure them properly with Hibernate. The problem is that it looks like Hibernate dynamically generates a class' package name when trying to find a class when it's doing its mapping. With one plug-in this scheme works, but across multiple plug-ins it's not working. It looks like Hibernate gets confused when dealing with Hibernate configuration files across multiple plug-ins.

我在我的应用程序使用的不同插件中的类名称完全相同,我希望能够使用Hibernate正确配置它们。问题是看起来Hibernate在尝试查找类时会动态生成类的包名称。有了一个插件,这个方案可行,但是在多个插件中,它无法正常工作。看起来Hibernate在跨多个插件处理Hibernate配置文件时会感到困惑。

Is this because each plug-in has its own class-loader? What is the best way to proceed to make this work with the existing plug-ins and Hibernate?

这是因为每个插件都有自己的类加载器吗?使用现有插件和Hibernate进行此工作的最佳方法是什么?

2 个解决方案

#1


The problem is, that every plugin has its own Classloader and Hibernate uses Reflection to find the right classes.

问题是,每个插件都有自己的Classloader,而Hibernate使用Reflection来找到合适的类。

I have a very nice article at home about exactly this problem, but this one is in German. I will try to explain what you need to do.

我家里有一篇非常好的文章,关于这个问题,但这篇文章是用德语写的。我会尝试解释你需要做什么。

In order to have the datastructure shared over several plugins, you have to put it in a plugin and enable a feature called buddy-policy. Lets say you have a main-application-plugin which is initiating hibernate on startup, this plugin needs to "see" the classes from the datastructure-plugin. To do this the main-plugin sets its Buddy-Policy to "registered" and the datastructure-plugin registers itself as a "buddy". Unfortunately you have to do this all directly in the manifest file, at least in 3.3 there was no way to do this in the editor.

为了使数据结构在多个插件上共享,您必须将其放入插件中并启用名为buddy-policy的功能。假设你有一个main-application-plugin,它在启动时启动hibernate,这个插件需要从数据结构插件“看到”这些类。为此,main-plugin将其Buddy-Policy设置为“registered”,datastructure-plugin将自己注册为“buddy”。不幸的是,您必须直接在清单文件中执行此操作,至少在3.3中无法在编辑器中执行此操作。

Once this buddy-policy works, Hibernate will also.

一旦这个伙伴政策有效,Hibernate也会。

I looked up my old application and here is how I did it.

我查看了我的旧应用程序,这就是我的工作方式。

  1. The main-application (toolseye.rcp) is dependent on the hibernate plugin (de.eye4eye.hibernate) and the datastructure-plugin (toolseye.datastructures)
  2. 主应用程序(toolseye.rcp)依赖于hibernate插件(de.eye4eye.hibernate)和datastructure-plugin(toolseye.datastructures)

  3. The hibernate-plugin specifies its buddy-policy as "registered"
  4. hibernate-plugin将其伙伴策略指定为“已注册”

  5. The datastructure-plugin registers itself to the hibernate-plugin
  6. datastructure-plugin将自己注册到hibernate-plugin

Here are the important lines:

以下是重要的内容:

Hibernate-plugin de.eye4eye.hibernate

Eclipse-BuddyPolicy: registered

Datastructure-plugin toolseye.datastructures

Eclipse-RegisterBuddy: de.eye4eye.hibernate

Put those line directly in the MANIFEST.MF

将这些行直接放在MANIFEST.MF中

Both plugins need to reexport their packages in order that the main application or whatever layer you have in between can use them. Hope that helped.

两个插件都需要重新导出它们的包,以便主应用程序或其间的任何层都可以使用它们。希望有所帮助。

#2


Just to make this complete.

只是为了完成这一点。

Instead of using Hibernate, EclipseLink could be used as JPA-provider in a Eclipse RCP application. EclipseLink is the former TopLink from Oracle and has been choosen to be the reference implementation for JPA 2.

EclipseLink可以在Eclipse RCP应用程序中用作JPA提供程序,而不是使用Hibernate。 EclipseLink是Oracle的前TopLink,已被选为JPA 2的参考实现。

The point for an RCP is, that EclipseLink is available as OSGI-Bundles (org.eclipse.persistence.jpa), and due to that it can load classes from another plugin without an additional buddy-policy.

RCP的意思是,EclipseLink可以作为OSGI-Bundles(org.eclipse.persistence.jpa)使用,并且由于它可以从另一个插件加载类而无需额外的伙伴策略。

Currently I was playing around, using the following project structure (Model-View-Presenter Pattern). The names in the brackets specify the dependecy plugins (not all are included, only the ones related to this question)

目前我正在玩,使用以下项目结构(Model-View-Presenter Pattern)。括号中的名称指定了依赖插件(并非所有插件都包含在内,只包含与此问题相关的插件)

  • rcp.mvp.view (rcp.mvp.presenter / rcp.mvp.model)
  • rcp.mvp.view(rcp.mvp.presenter / rcp.mvp.model)

  • rcp.mvp.presenter (rcp.mvp.data - data reexports the model, so this is not needed here) *
  • rcp.mvp.presenter(rcp.mvp.data - data reexports model,所以这里不需要)*

  • rcp.mvp.data (rcp.mvp.data.mysql / rcp.mvp.model / javax.persistence / org.eclipse.persistence.jpa)
  • rcp.mvp.data(rcp.mvp.data.mysql / rcp.mvp.model / javax.persistence / org.eclipse.persistence.jpa)

  • rcp.mvp.data.mysql - provides only the mysql-jdbc-driver. has to be inside the classpath
  • rcp.mvp.data.mysql - 仅提供mysql-jdbc-driver。必须在类路径内

  • rcp.mvp.model

In this scenario, the JPA provider in the data-plugin is able to load the classes from the model-plugin without a buddy-policy.

在这种情况下,data-plugin中的JPA提供程序能够在没有buddy-policy的情况下从model-plugin加载类。

*Note, the presenter is not dependent on any JPA packages since this is encapsulated by DAOs (the main reason why to use them still)

*注意,演示者不依赖于任何JPA包,因为它是由DAO封装的(仍然使用它们的主要原因)

Links

#1


The problem is, that every plugin has its own Classloader and Hibernate uses Reflection to find the right classes.

问题是,每个插件都有自己的Classloader,而Hibernate使用Reflection来找到合适的类。

I have a very nice article at home about exactly this problem, but this one is in German. I will try to explain what you need to do.

我家里有一篇非常好的文章,关于这个问题,但这篇文章是用德语写的。我会尝试解释你需要做什么。

In order to have the datastructure shared over several plugins, you have to put it in a plugin and enable a feature called buddy-policy. Lets say you have a main-application-plugin which is initiating hibernate on startup, this plugin needs to "see" the classes from the datastructure-plugin. To do this the main-plugin sets its Buddy-Policy to "registered" and the datastructure-plugin registers itself as a "buddy". Unfortunately you have to do this all directly in the manifest file, at least in 3.3 there was no way to do this in the editor.

为了使数据结构在多个插件上共享,您必须将其放入插件中并启用名为buddy-policy的功能。假设你有一个main-application-plugin,它在启动时启动hibernate,这个插件需要从数据结构插件“看到”这些类。为此,main-plugin将其Buddy-Policy设置为“registered”,datastructure-plugin将自己注册为“buddy”。不幸的是,您必须直接在清单文件中执行此操作,至少在3.3中无法在编辑器中执行此操作。

Once this buddy-policy works, Hibernate will also.

一旦这个伙伴政策有效,Hibernate也会。

I looked up my old application and here is how I did it.

我查看了我的旧应用程序,这就是我的工作方式。

  1. The main-application (toolseye.rcp) is dependent on the hibernate plugin (de.eye4eye.hibernate) and the datastructure-plugin (toolseye.datastructures)
  2. 主应用程序(toolseye.rcp)依赖于hibernate插件(de.eye4eye.hibernate)和datastructure-plugin(toolseye.datastructures)

  3. The hibernate-plugin specifies its buddy-policy as "registered"
  4. hibernate-plugin将其伙伴策略指定为“已注册”

  5. The datastructure-plugin registers itself to the hibernate-plugin
  6. datastructure-plugin将自己注册到hibernate-plugin

Here are the important lines:

以下是重要的内容:

Hibernate-plugin de.eye4eye.hibernate

Eclipse-BuddyPolicy: registered

Datastructure-plugin toolseye.datastructures

Eclipse-RegisterBuddy: de.eye4eye.hibernate

Put those line directly in the MANIFEST.MF

将这些行直接放在MANIFEST.MF中

Both plugins need to reexport their packages in order that the main application or whatever layer you have in between can use them. Hope that helped.

两个插件都需要重新导出它们的包,以便主应用程序或其间的任何层都可以使用它们。希望有所帮助。

#2


Just to make this complete.

只是为了完成这一点。

Instead of using Hibernate, EclipseLink could be used as JPA-provider in a Eclipse RCP application. EclipseLink is the former TopLink from Oracle and has been choosen to be the reference implementation for JPA 2.

EclipseLink可以在Eclipse RCP应用程序中用作JPA提供程序,而不是使用Hibernate。 EclipseLink是Oracle的前TopLink,已被选为JPA 2的参考实现。

The point for an RCP is, that EclipseLink is available as OSGI-Bundles (org.eclipse.persistence.jpa), and due to that it can load classes from another plugin without an additional buddy-policy.

RCP的意思是,EclipseLink可以作为OSGI-Bundles(org.eclipse.persistence.jpa)使用,并且由于它可以从另一个插件加载类而无需额外的伙伴策略。

Currently I was playing around, using the following project structure (Model-View-Presenter Pattern). The names in the brackets specify the dependecy plugins (not all are included, only the ones related to this question)

目前我正在玩,使用以下项目结构(Model-View-Presenter Pattern)。括号中的名称指定了依赖插件(并非所有插件都包含在内,只包含与此问题相关的插件)

  • rcp.mvp.view (rcp.mvp.presenter / rcp.mvp.model)
  • rcp.mvp.view(rcp.mvp.presenter / rcp.mvp.model)

  • rcp.mvp.presenter (rcp.mvp.data - data reexports the model, so this is not needed here) *
  • rcp.mvp.presenter(rcp.mvp.data - data reexports model,所以这里不需要)*

  • rcp.mvp.data (rcp.mvp.data.mysql / rcp.mvp.model / javax.persistence / org.eclipse.persistence.jpa)
  • rcp.mvp.data(rcp.mvp.data.mysql / rcp.mvp.model / javax.persistence / org.eclipse.persistence.jpa)

  • rcp.mvp.data.mysql - provides only the mysql-jdbc-driver. has to be inside the classpath
  • rcp.mvp.data.mysql - 仅提供mysql-jdbc-driver。必须在类路径内

  • rcp.mvp.model

In this scenario, the JPA provider in the data-plugin is able to load the classes from the model-plugin without a buddy-policy.

在这种情况下,data-plugin中的JPA提供程序能够在没有buddy-policy的情况下从model-plugin加载类。

*Note, the presenter is not dependent on any JPA packages since this is encapsulated by DAOs (the main reason why to use them still)

*注意,演示者不依赖于任何JPA包,因为它是由DAO封装的(仍然使用它们的主要原因)

Links