persistence.xml用于多个持久性单元 [英] persistence.xml for multiple persistence units

查看:110
本文介绍了persistence.xml用于多个持久性单元的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将相同的实体持久保存到MySQL和Postgres数据库中(这主要是为了识别任何不一致之处,并找出进行双重写入的任何问题的详细信息-我已经在这里遇到过) .我发现的文章都描述了依赖于其他框架的解决方案.我正在尝试使用现成的Glassfish 4.0,JPA 2.1和EclipseLink 2.5作为JPA提供程序来解决此问题.我正在使用Eclipse,并且意识到IDE不支持在persistence.xml文件中配置多个持久性单元,因此我直接为此编写了XML.

I'm trying to persist the same entity to both MySQL and Postgres databases (this is primarily to identify any inconsistencies, and work out the details of any issues doing the dual-write -- which I've run into here). The articles I've found have all described solutions that depend on additional frameworks. I'm trying to solve this using Glassfish 4.0 out-of-the-box, JPA 2.1 with EclipseLink 2.5 as the JPA provider. I'm using Eclipse, and realize that the IDE doesn't support configuring multiple persistence units in the persistence.xml file, so I'm writing the XML for that directly.

我希望在代码中执行类似的操作(使用相同的方法):

I was expecting to do something like this in the code (in the same method):

@PersistenceContext(name = "MyAppMySQLPU")
EntityManager emMySQL;
@PersistenceContext(name = "MyAppPostgresPU")
EntityManager emPostgres;
//...etc...
MyThing thing = new MyThing();
//...etc...
emMySQL.persist(thing);
emPostgres.persist(thing);

,并使用包含以下内容的persistence.xml文件:

and use a persistence.xml file containing this:

  <persistence-unit name="MyAppPostgresPU">
    <jta-data-source>jdbc/PostgresPool_test</jta-data-source>
    <class>model.MyThing</class>
  </persistence-unit>

  <persistence-unit name="MyAppMySQLPU">
    <jta-data-source>jdbc/MySQLPool_test</jta-data-source>
    <class>model.MyThing</class>
  </persistence-unit>

执行此操作时,出现以下错误:

When I do this, I get the following error:

SEVERE: Exception while invoking class org.glassfish.persistence.jpa.JPADeployer prepare method
SEVERE: Exception while preparing the app
SEVERE: Exception while preparing the app : Could not resolve a persistence unit corresponding to the persistence-context-ref-name [MyAppPostgresPU] in the scope of the module called [MyApp]. Please verify your application.

但是,如果我仅包含一个<persistence-unit>短语(与哪个短语无关),则该实体将持久保存到关联的数据库中-我只是不知道如何使它与两个数据库一起使用同时进行(没有在其他框架中利用持久性功能).

But, If I include only one of the <persistence-unit> phrases (doesn't matter which one), the entity is persisted to the associated database -- I just can't figure out how to get it to work with both at the same time (without leveraging persistence functionality in additional frameworks).

推荐答案

使其正常运行;必须要做的几件事.似乎其中的关键部分是,为了以我采用的方法使用多个数据库,需要将连接池类型设置为使用分布式事务.由于这本质上是一个实验,因此两个db持久存储都不需要 处于同一事务中,但是那样做就不是问题. (本文有助于从错误消息中识别出来.还必须按照此处,以启用准备好的交易.

Got it working; several things had to be done. It seems a key part of this is that in order to use the multiple databases with the approach I was taking, the connection pool type needs to be set to use distributed transactions. Since this is essentially an experiment, both db persists didn't need to be in the same transaction, but it's not a problem for it to be that way. (This article was helpful in identifying that from the error messages). It was also necessary to change the Postgres parameters as described here, to enable prepared transactions.

一切顺利:

(1)在Glassfish中:
在JDBC连接池中,将两个数据库的资源类型都更改为javax.sql.XADataSource.将Postgres的数据源类名更改为org.postgresql.xa.PGXADataSource;将MySQL的数据源类名更改为com.mysql.jdbc.jdbc2.optional.MysqlXADataSource.

(1) In Glassfish:
In the JDBC Connection pools, change the resource type for both db's to javax.sql.XADataSource. Change Datasource Classname for Postgres to org.postgresql.xa.PGXADataSource; change Datasource Classname for MySQL to com.mysql.jdbc.jdbc2.optional.MysqlXADataSource.

(2)在Posgres配置(postgresql.config)中:
启用max_prepared_transactions并将其设置为大于max_connections的1. (我必须同时使用这两个参数来查找不会耗尽所有可用共享内存的东西;但是由于这只是一个实验,因此减少数据库连接数与增加共享内存是可以的)

(2) In Posgres configuration (postgresql.config):
Enable max_prepared_transactions and set it to be 1 greater than max_connections. (I had to play around with both parameters to find something that didn't blow out all available shared memory; but since this is only an experiment, decreasing number of db connections vs increasing shared memory is OK)

(3)在代码中:
@PersistenceContext(name="...")更改为@PersistenceContext(unitName="...")

(3) In the code:
Change @PersistenceContext(name="...") to @PersistenceContext(unitName="...")

对此答案"进行警告-这对我来说大部分是新的,因此这可能不是解决此问题的最优雅的方法.如果有人可以提供最佳实践"来解决这个问题,我将非常有兴趣知道.

Caveat on this "answer" -- Most of this is new for me, so this may not be the most elegant way to handle this. If anyone can provide a "best practice" to solve this, I would be very interested to know.

这篇关于persistence.xml用于多个持久性单元的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆