【问题标题】:Drools Stateful Knowledge Session using persistence使用持久性的 Drools 状态知识会话
【发布时间】:2015-06-12 13:42:40
【问题描述】:

我正在创建一个 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 驱动程序一起使用。

【问题讨论】:

标签: java jpa jdbc drools jbpm


【解决方案1】:

最后,我成功了。我犯的最重要的错误是我试图使用 EclipseLink 作为 JPA 提供者。这种方法行不通,因为除了自定义持久性类之外,Drools 还使用另外两个带持久性注释的类:org.drools.persistence.info.SessionInfo 和 org.drools.persistence.info.WorkItemInfo。这两个包含未使用 JPA 时间注释进行注释的日期字段。它们似乎是专门为 Hibernate 量身定制的。

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

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

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

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

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

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-06-15
    • 1970-01-01
    • 2019-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-05
    • 2017-09-09
    相关资源
    最近更新 更多