对于长篇故事感到抱歉,但我想知道为什么我们正在做我们正在做的事情。
我们的应用程序目前使用Hibernate 3.6,我们希望升级到Hibernate 4.3。
专门编写应用程序是为了避免使用persistence.xml
配置JPA并创建EntityManagerFactory
,而是使用Hibernate的Ejb3Configuration
类,如下所示(示例):
Properties properties = new Properties();
properties.put("javax.persistence.provider", "org.hibernate.ejb.HibernatePersistence");
properties.put("javax.persistence.transactionType", "RESOURCE_LOCAL");
properties.put("hibernate.dialect", "org.hibernate.dialect.Oracle10gDialect");
properties.put("hibernate.show_sql", "false");
properties.put("hibernate.format_sql", "true");
Ejb3Configuration cfg = new Ejb3Configuration();
cfg.addProperties(properties);
DataSource dataSource = dataSourceProvider.get();
cfg.setDataSource(dataSource);
//add the annotated classes
cfg.addAnnotatedClass(SomePersistentObject.class);
EntityManagerFactory factory = cfg.buildEntityManagerFactory();
我们这样做的原因是因为我们有一个部署到Tomcat的Web应用程序(war文件),它提供了“核心”功能。然后,我们在爆炸的/WEB-INF/lib
目录中安装我们称之为“客户端捆绑”的jar文件。 “客户端捆绑包”包含对Web应用程序的现有“核心”行为的覆盖。这允许我们在Web应用程序的一个实例中为多个客户端提供服务,每个客户端都具有来自“核心”行为的各种自定义。我们根据传入HTTP请求的域或子域知道要使用哪个客户端捆绑包。
每个客户端包总是获得自己的数据库实例,因此每个客户端包定义自己的EntityManagerFactory
。模式几乎完全相同,但客户端包可以根据需要添加新的持久化类。
因此,我们在Java中进行JPA配置的原因是每个客户端包都扩展了“核心”类并添加了自己的实体类。 XML非常适合继承,而XML很糟糕。如果我们必须通过XML进行配置,那么每个客户端包都需要复制核心的persistence.xml
并从那里更新它。我宁愿使用继承来复制/粘贴。
我认为我们有一个非常有效的用例来优先选择通过Java而不是XML的JPA配置。
我的问题:Hibernate 4.3是否允许这种方式?如果是这样,我该怎么办呢?
如果没有,是否有人建议如何在使用XML配置时尽可能简化上述场景?
单个Web应用程序中的多个jar文件可以包含/META-INF/persistence.xml
个文件,还是需要以另一种方式定义多个持久性单元?
谢谢!!!
-Ryan
答案 0 :(得分:2)
我通过在引导JPA之前动态地将新的persistence.xml
文件写入Web应用程序的类路径来克服了这个问题。
当Web应用程序启动时,将读取所有客户端软件包的JPA配置,然后将单个persistence.xml
文件写入类路径。每个客户端捆绑包都在persistence-unit
内以persistence.xml
的形式获得自己的条目。
然后,在写入新的persistence.xml
之后,JPA被引导。显然,JPA并不知道或关心persistence.xml
文件是动态编写的。
这似乎有点像黑客,但我无法找出任何其他方法来做到这一点。一个很好的好处是它让我远离Hibernate特定的API,所以如果我想切换到像DataAucleus这样的JPA提供者,我将有灵活性。