持久性在远程会话bean

时间:2017-12-01 16:58:01

标签: hibernate jpa glassfish eclipselink persistence

我在两个不同的Glassfish域之间进行通信的两个JEE应用程序之间存在持久性问题。

基本结构

  • 我们在Glassfish服务器上的两个不同域上部署了两个JEE应用程序
  • Application1部署在domain1上并使用数据库Database1
  • Application2部署在domain2上并使用数据库Database2
  • Application1通过远程EJB与Application2通信 会话bean

另一种观点

  • Glassfish 4.0
    • domain1的
      • Application1< =>数据库1
        • 应用程序1-EJB
        • 应用程序1-战争
    • DOMAIN2
      • Application2< => DATABASE2
        • 应用2-EJB
        • Application2-war

环境

  • 我们正在使用Glassfish 4.0
  • 我们正在使用JDK7 / JEE7来构建和部署应用程序 Glassfish的
  • 我们正在使用EclipseLink来实现应用程序中的持久性,我 已启用eclipse日志记录以检查日志中的请求
  • 我们正在将MySQL用于两个数据库
  • 我们正在使用XADataSource来执行两者的请求 同一事务中的数据库

我使用的测试用例

  1. 来自 Application1-war 的托管bean从 Application1-ejb 调用本地会话bean(当用户在浏览器中执行操作时)
  2. 来自 Application1-ejb 的本地会话bean将从 Application2-ejb
  3. 调用远程会话bean
  4. 来自 Application2-ejb 的远程会话bean将在数据库中保留一个实体 Database2 em.persist(entity2)
  5. 来自 Application1-ejb 的本地会话bean将在数据库 Database1 中保留实体:em.persist(entity1)
  6. 不知何故,它应该与我们使用`XADataSource`的事务相同 因此,如果由于任何原因发生运行时异常,则不应该保留实体。

    问题

    第一次调用 Application1-ejb 的方法时,它可以工作:

    • Application2 将实体持久保存在数据库 Database2
    • Application1 将实体持久保存在数据库 Database1

    可以在日志中看到请求,我可以在 Database1 Database2 中看到新实体。

    下次调用 Application1-ejb 的方法时,它将不起作用:

    • Application1 能够调用 Application2 ,但即使 Application2 调用em.persist(entity2),它也不会将实体持久化数据库 Database2
    • Application1 将实体持久存储在 Database1

    请求可以在 Application1 的日志中看到,但 Application2 的日志中看不到任何请求。

    可以在 Database1 中看到新实体 但是 Database2 中没有新的实体 在浏览器中,看起来服务器没有给客户端任何响应。

    我尝试了几件事......

    • 在较新的Glassfish(4.0到5.0)上部署项目:问题仍然存在
    • 更新MySQL的Java连接器(5.1.23到5.1.45):问题仍然存在
    • 更新EclipseLink(2.5到2.5.2):问题仍然存在

    休眠

    如果我使用Hibernate而不是EclipseLink,它将按预期工作。但是迁移到Hibernate并不是我们现在可以承受的,因为我们必须迁移大型JEE应用程序。

    em.flush()

    如果我强制 Application2-ejb em.persist(entity2)之后刷新,它将每次都有效,并且浏览器总是从服务器接收响应。

    但是如果我刷新,则意味着如果在某一点发生异常,则实体将持久存储在 Database2 中(因为刷新),并且中不会保留任何实体Database1 (因为例外),这也不是我们想要的。

    产生问题的一些代码

    应用1 / 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();
        }
    }
    

    应用1 /与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>
    

    应用1 / 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>
    

    应用2 / SessionBean.java

    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());
        }
    }
    

    应用2 / 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="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>
    

    Application2Remote / SessionBeanRemote.java

    package application2.sessionbeans.remote;
    
    import javax.ejb.Remote;
    
    @Remote
    public interface SessionBeanRemote {
    
        public void test();
    
    }
    

    我试图让这个例子尽可能简单。

    这里是否有人能够在不同的Glassfish域之间保持实体没有任何问题?

    我是否在persistence.xml中缺少一个可以使其正常工作的属性?

0 个答案:

没有答案