使用持久性来破坏状态知识会话

时间:2015-06-12 13:42:40

标签: java jpa jdbc drools jbpm

我正在创建一个Drools有状态会话,如JBPM持久性文档中所述: http://docs.jboss.org/jbpm/v5.1/javadocs/org/drools/persistence/jpa/JPAKnowledgeService.html

但是,我遇到了以下异常

javax.persistence.TransactionRequiredException: joinTransaction has been called on a resource-local EntityManager which is unable to register for a JTA transaction.

我的代码是:

EntityManagerFactory emf = Persistence.createEntityManagerFactory("metadata.model");
Environment env = KnowledgeBaseFactory.newEnvironment();
env.set(EnvironmentName.ENTITY_MANAGER_FACTORY, emf);
env.set(EnvironmentName.TRANSACTION_MANAGER, TransactionManagerServices.getTransactionManager());
env.set(EnvironmentName.TRANSACTION,   TransactionManagerServices.getTransactionManager());
KieServices ks = KieServices.Factory.get();
KieContainer kContainer = ks.getKieClasspathContainer();
KieBase kBase = kContainer.getKieBase();
StatefulKnowledgeSession kSession = JPAKnowledgeService.newStatefulKnowledgeSession(kBase, null, env);

在最后一行抛出异常。事先,我已按照上述文档中的描述绑定了JDBC JTA数据源。

PoolingDataSource ds = new PoolingDataSource();
ds.setUniqueName("jdbc/BitronixJTADataSource");
ds.setClassName("com.mysql.jdbc.jdbc2.optional.MysqlXADataSource");
ds.setMaxPoolSize(3);
ds.setAllowLocalTransactions(true);
ds.getDriverProperties().put("user", "root");
ds.getDriverProperties().put("password", "****");
ds.getDriverProperties().put("URL", "jdbc:mysql://localhost:3306/metadatadb");
ds.init();

我正在使用EclipseLink持久性提供程序和MySQL JDBC驱动程序。

1 个答案:

答案 0 :(得分:0)

最后,我让它发挥了作用。我犯的最重要的错误是我试图将EclipseLink用作JPA提供程序。这种方法不起作用,因为除了自定义持久性类之外,Drools还使用另外两个持久性注释类:org.drools.persistence.info.SessionInfoorg.drools.persistence.info.WorkItemInfo。这两个包含未使用JPA Temporal注释注释的Date字段。它们似乎是专门为Hibernate量身定制的。

我注意到的另一个重要方面是在设置环境变量后需要添加以下行:

env.set(EnvironmentName.OBJECT_MARSHALLING_STRATEGIES,
            new ObjectMarshallingStrategy[] {
                    new JPAPlaceholderResolverStrategy(domainEnv),
                    new SerializablePlaceholderResolverStrategy(
                            ClassObjectMarshallingStrategyAcceptor.DEFAULT) });

执行此操作是为了宣布您打算使用JPA保持当前会话状态。

但是,我之前提到的异常是由于EclipseLink正在创建“ResourceLocal”事务包装器这一事实,即使在persistence.xml中明确指定了JTA。这是因为没有指定目标服务器属性。因此,没有外部事务控制器附加到创建的数据库会话,并且提供的包装器根本不支持joinTransaction操作。要解决此问题,请将以下行添加到persistence.xml文件中:

<property name="eclipselink.target-server" value="JBoss"/>

在初始化数据源之前,添加:

Configuration conf = TransactionManagerServices.getConfiguration();
conf.setJndiUserTransactionName("java:/TransactionManager");

当然,我假设正在使用BTM。