Hibernate Persist在远程会话bean上未按预期工作
我在两个不同Glassfish域之间通信的两个JEE应用程序之间存在持久性问题 基本结构Hibernate Persist在远程会话bean上未按预期工作,hibernate,jpa,glassfish,eclipselink,persistence,Hibernate,Jpa,Glassfish,Eclipselink,Persistence,我在两个不同Glassfish域之间通信的两个JEE应用程序之间存在持久性问题 基本结构 我们在Glassfish服务器的两个不同域上部署了两个JEE应用程序 Application1部署在domain1上并使用数据库Database1 Application2部署在domain2上,并使用数据库Database2 Application1通过远程EJB与Application2通信 会话bean 另一种观点 玻璃鱼4.0 域1 应用程序1数据库1 应用程序1 ejb 应用1战争
- 我们在Glassfish服务器的两个不同域上部署了两个JEE应用程序
- Application1部署在domain1上并使用数据库Database1
- Application2部署在domain2上,并使用数据库Database2
- Application1通过远程EJB与Application2通信 会话bean
- 玻璃鱼4.0
- 域1
- 应用程序1数据库1
- 应用程序1 ejb
- 应用1战争
- 应用程序1数据库1
- 域2
- 应用程序2数据库2
- 应用程序2 ejb
- 应用2战争
- 应用程序2数据库2
- 域1
- 我们正在使用Glassfish 4.0
- 我们使用JDK7/JEE7在 玻璃鱼
- 我们在应用程序中使用EclipseLink实现持久性,I 已启用eclipse日志来检查日志中的请求
- 我们对这两个数据库都使用MySQL
- 我们使用XADataSource能够在这两个服务器上执行请求 同一事务中的数据库
我正在使用的测试用例
em.persist(entity2)
em.persist(entity1)
因此,如果出于任何原因发生运行时异常,则不应持久化实体 问题 第一次调用Application1 ejb的方法时,它会工作:
- Application2将实体持久化到数据库2中
- Application1将实体持久化到数据库1中
- Application1可以调用Application2,但即使Application2调用了
,它也不会将实体持久化到数据库2中em.persist(entity2)
- Application1将实体持久化到数据库1中
但在数据库中看不到新实体2。
在浏览器中,服务器似乎没有向客户端提供任何响应 我试过几种方法。。。
- 在较新的Glassfish(4.0到5.0)上部署projets:问题仍然存在
- 更新MySQL的Java连接器(5.1.23到5.1.45):问题仍然存在
- 更新EclipseLink(2.5到2.5.2):问题仍然存在
em.persist(entity2)
之后强制Application2EJB刷新,它每次都会工作,并且浏览器总是收到来自服务器的响应
但是如果我刷新,这意味着如果在某一点发生异常,一个实体将被持久化到Database2(因为刷新),而没有实体将被持久化到Database1(因为异常),这不是我们想要的
生成问题的一些代码 Application1/SessionBean.java
package application1.sessionbeans;
import application1.entities.Entity1;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import application2.sessionbeans.remote.SessionBeanRemote;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
@Stateless
public class SessionBean implements SessionBeanLocal {
@EJB(name = "SessionBeanRemote-ejbref")
private SessionBeanRemote sessionBeanRemote;
@PersistenceContext
private EntityManager em;
@Override
public void test() {
System.out.println("SessionBean Application1");
em.persist(new Entity1());
sessionBeanRemote.test();
}
}
package application2.sessionbeans;
import application2.entities.Entity2;
import application2.sessionbeans.remote.SessionBeanRemote;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
@Stateless
public class SessionBean implements SessionBeanRemote {
@PersistenceContext
private EntityManager em;
@Override
public void test() {
System.out.println("sessionBean Application2");
em.persist(new Entity2());
}
}
Application1/glassfish-ejb-jar.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE glassfish-ejb-jar PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 EJB 3.1//EN" "http://glassfish.org/dtds/glassfish-ejb-jar_3_1-1.dtd">
<glassfish-ejb-jar>
<enterprise-beans>
<ejb>
<ejb-name>SessionBean</ejb-name>
<jndi-name>java:global/EnterpriseApplication1/EnterpriseApplication1-ejb/SessionBean</jndi-name>
<ejb-ref>
<ejb-ref-name>SessionBeanRemote-ejbref</ejb-ref-name>
<jndi-name>corbaname:iiop:localhost:4537#java:global/EnterpriseApplication2/EnterpriseApplication2-ejb/SessionBean</jndi-name>
</ejb-ref>
</ejb>
</enterprise-beans>
</glassfish-ejb-jar>
Application2/persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="EnterpriseApplication1-ejbPU" transaction-type="JTA">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>aEnercomDS</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/>
</properties>
</persistence-unit>
</persistence>
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="EnterpriseApplication2-ejbPU" transaction-type="JTA">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>AEnercomCollectData-DS</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/>
</properties>
</persistence-unit>
</persistence>
我试图使这个例子尽可能简单 这里是否有人能够在不同的Glassfish域之间保持实体而没有任何问题
persistence.xml中是否缺少一个属性来实现此功能?“但如果我刷新,这意味着如果某个点发生异常,则将在Database2中持久化一个实体(因为刷新),而在Database1中不会持久化任何实体(因为异常),这不是我们想要的——为什么会发生?刷新与设置transactionYes不同,但刷新会导致实体管理器写入数据库。我还可以说,当Application1和Application2应用程序位于同一个Glassfish域上时,一切都按预期工作。在数据库中写入与提交事务仍然不同。这就是拥有一个事务的全部意义,能够向数据库发出多个写语句,并且仍然能够在出现任何错误时回滚它们。换句话说,如果您使用flush解决方案,您应该很好您应该设置一个更精细的日志级别,以找出日志中可能出现的错误。不需要刷新,但奇怪的是,您的方法返回时不会抛出错误或出现问题的迹象。@crizzis我完全同意,但似乎我已经找到了刷新后无法正确回滚的原因。我们使用MyISAM作为MySQL的默认存储引擎。我刚刚对InnoDB做了相同的测试,如果我在
em.flush()
”之后抛出异常,那么这次回滚确实会发生。但是如果我flush,这意味着如果在某一点上发生异常,一个实体将被持久化到Database2中(因为flush),而没有实体将被持久化到Database中
package application2.sessionbeans.remote;
import javax.ejb.Remote;
@Remote
public interface SessionBeanRemote {
public void test();
}