简体   繁体   English

使用持久性进行Drools状态知识会议

[英]Drools Stateful Knowledge Session using persistence

I am creating a Drools stateful session as described in the JBPM persistence documentation: http://docs.jboss.org/jbpm/v5.1/javadocs/org/drools/persistence/jpa/JPAKnowledgeService.html 我正在按照JBPM持久性文档中的说明创建Drools状态会话: http : //docs.jboss.org/jbpm/v5.1/javadocs/org/drools/persistence/jpa/JPAKnowledgeService.html

However, I came across the following exception 但是,我遇到了以下异常

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

My code is : 我的代码是:

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

The exception is thrown at the last line. 在最后一行抛出异常。 Beforehand, I have bound the JDBC JTA Datasource as described in the aforementioned documentation. 之前,我已经按照上述文档中的说明绑定了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();

I am using the EclipseLink persistence provider alongside the MySQL JDBC driver. 我正在将EclipseLink持久性提供程序与MySQL JDBC驱动程序一起使用。

Finally, I have made it work. 最后,我使它工作了。 The most important mistake I was making was that I was trying to use EclipseLink as JPA provider. 我犯的最重要的错误是我试图将EclipseLink用作JPA提供程序。 This approach will not work, since besides the custom persistency classes, Drools uses two other persistency-annotated classes: org.drools.persistence.info.SessionInfo and org.drools.persistence.info.WorkItemInfo . 该方法行不通,因为除了自定义持久性类之外,Drools还使用其他两个org.drools.persistence.info.SessionInfo持久性注释的类: org.drools.persistence.info.SessionInfoorg.drools.persistence.info.WorkItemInfo These two contain Date fields which are not annotated with the JPA Temporal annotation. 这两个包含日期字段,这些字段未使用JPA Temporal注释进行注释。 They appear to be tailored specifically for Hibernate. 它们似乎是专门为Hibernate量身定制的。

Another important aspect that came to my attention is the need to add the following line after setting the environment variable: 我注意到的另一个重要方面是在设置环境变量之后需要添加以下行:

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

This is performed in order to announce your intention to persist the current session state using JPA. 执行此操作是为了宣布您打算使用JPA保留当前会话状态。

The exception I mentioned above was, however, due to the fact that EclipseLink was creating a "ResourceLocal" transaction wrapper even though JTA was explicitly specified in persistence.xml. 但是,我上面提到的异常是由于即使在persistence.xml中明确指定了JTA,EclipseLink仍在创建“ ResourceLocal”事务包装器。 This is due to the fact that there was no target-server property specified. 这是由于没有指定目标服务器属性。 Consequently, there were no external transaction controllers attached to the database session that was created and the wrapper that was provided simply couldn't support the joinTransaction operation. 因此,创建的数据库会话没有附加外部事务控制器,并且提供的包装程序根本不支持joinTransaction操作。 To work around this issue, add the following line to your persistence.xml file: 要变通解决此问题,将以下行添加到您的persistence.xml文件:

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

and before initializing the datasource, add: 在初始化数据源之前,添加:

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

Of course, I am presuming that BTM is being used. 当然,我假设正在使用BTM。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM