我试图在一个Spring Boot Maven项目中用Kiesession
的持久性特性实现Drools。遵循此文档进行实现。我能够在普通的Java应用程序中做到这一点,但我在Spring Boot应用程序中尝试做到这一点时遇到了异常。
下面是实现。
项目结构
@Configuration
public class PersistentDroolConfig {
public static Long KIE_SESSION_ID;
private final KieServices kieServices = KieServices.Factory.get();
@Bean
public KieSession kieSession() {
KieSession kieSession = kieServices.getStoreServices().newKieSession(getKieBase(), null, getEnv());
PersistentDroolConfig.KIE_SESSION_ID = kieSession.getIdentifier();
return kieSession;
}
public KieServices getKieServices() {
initDataSource();
return kieServices;
}
public KieBase getKieBase() {
KieFileSystem kieFileSystem = kieServices.newKieFileSystem();
kieFileSystem.write(ResourceFactory.newClassPathResource("rules/rules.drl"));
final KieRepository kieRepository = kieServices.getRepository();
kieRepository.addKieModule(kieRepository::getDefaultReleaseId);
KieBuilder kb = kieServices.newKieBuilder(kieFileSystem);
kb.buildAll();
KieModule kieModule = kb.getKieModule();
KieContainer kieContainer = kieServices.newKieContainer(kieModule.getReleaseId());
return kieContainer.getKieBase();
}
public Environment getEnv() {
Environment env = kieServices.newEnvironment();
env.set(EnvironmentName.ENTITY_MANAGER_FACTORY, Persistence.createEntityManagerFactory("org.drools.persistence.jpa"));
env.set(EnvironmentName.TRANSACTION_MANAGER, TransactionManagerServices.getTransactionManager());
return env;
}
private void initDataSource() {
PoolingDataSource ds = new PoolingDataSource();
ds.setUniqueName("jdbc/BitronixJTADataSource");
ds.setClassName("com.mysql.cj.jdbc.MysqlXADataSource");
ds.setMaxPoolSize(3);
ds.setAllowLocalTransactions(true);
ds.getDriverProperties().put("user", "root");
ds.getDriverProperties().put("password", "1234");
ds.getDriverProperties().put("URL", "jdbc:mysql://localhost:3306/drool_demo");
ds.init();
}
}
@RestController
public class OfferController {
@Autowired
private KieSession kieSession;
@GetMapping("/order/{card-type}/{price}")
public Order order(@PathVariable("card-type") String cardType, @PathVariable int price) {
Order order = new Order(cardType, price);
kieSession.insert(order);
kieSession.fireAllRules();
return order;
}
}
事实类
public class Order implements Serializable {
private String name;
private String cardType;
private int discount;
private int price;
public Order(String cardType, int price) {
this.cardType = cardType;
this.price = price;
}
// setters and getters
// toString()
}
persistence.xml
<persistence version="2.0"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd
http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_2_0.xsd"
xmlns:orm="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/persistence">
<persistence-unit name="org.drools.persistence.jpa"
transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>jdbc/BitronixJTADataSource</jta-data-source>
<class>org.drools.persistence.info.SessionInfo</class>
<class>org.drools.persistence.info.WorkItemInfo</class>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
<property name="hibernate.max_fetch_depth" value="3" />
<property name="hibernate.hbm2ddl.auto" value="create" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.BTMTransactionManagerLookup" />
</properties>
</persistence-unit>
</persistence>
pom.xml文件中包含的依赖关系如下:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.github.marcus-nl.btm</groupId>
<artifactId>btm</artifactId>
<version>3.0.0-mk1</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-decisiontables</artifactId>
<version>${drools-version}</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-core</artifactId>
<version>${drools-version}</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-compiler</artifactId>
<version>${drools-version}</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-persistence-jpa</artifactId>
<version>${drools-version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
Caused by: org.hibernate.engine.jndi.JndiException: Unable to lookup JNDI name [jdbc/BitronixJTADataSource]
Caused by: javax.naming.NameNotFoundException: unable to find a bound object at name 'jdbc/BitronixJTADataSource'
Caused by: org.hibernate.HibernateException: Unable to perform isolated work
Caused by: java.sql.SQLSyntaxErrorException: Table 'drool_demo.sessioninfo_id_seq' doesn't exist
Hibernate: drop table if exists SessionInfo
Hibernate: drop table if exists WorkItemInfo
Hibernate: create table SessionInfo (id bigint not null auto_increment, lastModificationDate datetime, rulesByteArray longblob, startDate datetime, OPTLOCK integer, primary key (id)) type=MyISAM
2020-10-09 23:49:59.554 WARN 11376 --- [ main] o.h.t.s.i.ExceptionHandlerLoggedImpl : GenerationTarget encountered exception accepting command : Error executing DDL "create table SessionInfo (id bigint not null auto_increment, lastModificationDate datetime, rulesByteArray longblob, startDate datetime, OPTLOCK integer, primary key (id)) type=MyISAM" via JDBC Statement
org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL "create table SessionInfo (id bigint not null auto_increment, lastModificationDate datetime, rulesByteArray longblob, startDate datetime, OPTLOCK integer, primary key (id)) type=MyISAM" via JDBC Statement
Caused by: java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'type=MyISAM' at line 1
Hibernate: create table WorkItemInfo (workItemId bigint not null auto_increment, creationDate datetime, name varchar(255), processInstanceId bigint not null, state bigint not null, OPTLOCK integer, workItemByteArray longblob, primary key (workItemId)) type=MyISAM
2020-10-09 23:49:59.556 WARN 11376 --- [ main] o.h.t.s.i.ExceptionHandlerLoggedImpl : GenerationTarget encountered exception accepting command : Error executing DDL "create table WorkItemInfo (workItemId bigint not null auto_increment, creationDate datetime, name varchar(255), processInstanceId bigint not null, state bigint not null, OPTLOCK integer, workItemByteArray longblob, primary key (workItemId)) type=MyISAM" via JDBC Statement
org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL "create table WorkItemInfo (workItemId bigint not null auto_increment, creationDate datetime, name varchar(255), processInstanceId bigint not null, state bigint not null, OPTLOCK integer, workItemByteArray longblob, primary key (workItemId)) type=MyISAM" via JDBC Statement
Caused by: java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'type=MyISAM' at line 1
我想你的配置有问题。从未调用PersistentDroolConfig
类的GetKieservices
方法,因此,初始化数据源的initDataSource
方法也不会调用。
也许您可以尝试修改persistentdroolconfig
,如下所示:
@Configuration
public class PersistentDroolConfig {
public static Long KIE_SESSION_ID;
private KieServices kieServices;
@PostContruct
private void init() {
this.initDataSource();
this.kieServices = KieServices.Factory.get();
}
@Bean
public KieSession kieSession() {
KieSession kieSession;
if (KIE_SESSION_ID == null) {
kieSession = createNewKieSession();
KIE_SESSION_ID = kieSession.getIdentifier();
return kieSession;
} else {
kieSession = getPersistentKieSession();
KIE_SESSION_ID = kieSession.getIdentifier();
return kieSession;
}
}
public KieBase getKieBase() {
KieFileSystem kieFileSystem = kieServices.newKieFileSystem();
kieFileSystem.write(ResourceFactory.newClassPathResource("rules/rules.drl"));
final KieRepository kieRepository = kieServices.getRepository();
kieRepository.addKieModule(new KieModule() {
@Override
public ReleaseId getReleaseId() {
return kieRepository.getDefaultReleaseId();
}
});
KieBuilder kb = kieServices.newKieBuilder(kieFileSystem);
kb.buildAll();
KieModule kieModule = kb.getKieModule();
KieContainer kieContainer = kieServices.newKieContainer(kieModule.getReleaseId());
KieBase kieBase = kieContainer.getKieBase();
return kieBase;
}
public Environment getEnv() {
Environment env = kieServices.newEnvironment();
env.set(EnvironmentName.ENTITY_MANAGER_FACTORY, Persistence.createEntityManagerFactory("org.drools.persistence.jpa"));
env.set(EnvironmentName.TRANSACTION_MANAGER, TransactionManagerServices.getTransactionManager());
return env;
}
private KieSession createNewKieSession() {
KieSession kieSession = kieServices.getStoreServices().newKieSession(getKieBase(), null, getEnv());
PersistentDroolConfig.KIE_SESSION_ID = kieSession.getIdentifier();
return kieSession;
}
private KieSession getPersistentKieSession() {
return kieServices.getStoreServices().loadKieSession(KIE_SESSION_ID, getKieBase(), null, getEnv());
}
private void initDataSource() {
PoolingDataSource ds = new PoolingDataSource();
ds.setUniqueName("jdbc/BitronixJTADataSource");
ds.setClassName("com.mysql.cj.jdbc.MysqlXADataSource");
ds.setMaxPoolSize(3);
ds.setAllowLocalTransactions(true);
ds.getDriverProperties().put("user", "root");
ds.getDriverProperties().put("password", "1234");
ds.getDriverProperties().put("URL", "jdbc:mysql://localhost:3306/drool_demo");
ds.init();
}
}
更新
<property name="hibernate.id.new_generator_mappings" value="false" />
它经常用于Drools示例和测试用例中。请参阅这篇伟大的Vlad Mihalcea文章,以获得深入的解释。
此配置属性的包含产生了一个与所使用的MySQL方言有关的新问题。应改为:
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/>
使用此配置,应用程序应该可以顺利运行。
转换器.KT FoodDatabase.kt 当我运行以下代码创建数据库时: 我还附上我的评分文件: 有人遇到过这个问题吗?
我已经在这个问题上工作了两天了,现在我没有主意了。 下面是entity和dao类: 抽象性: 域道: 我不认为问题出在EntityManager或dao类中,因为EntityManager(find())至少有一个方法起作用。我会很感激和帮忙的。
我正在尝试使用来持久化一个实体。当我自己处理事务时,我的测试用例工作(数据保存在db中)。 (实体管理器来自我的DAO类扩展的模板类) 当我配置spring来处理事务时,它会停止分发数据。 测试上下文。xml: UsersRepositoryTest: 堆栈跟踪: 从stacktrace中可以看到,事务似乎已经启动和完成,但没有生成sql插入,也没有数据插入到数据库中(数据回滚设置为false)
参考Link,我使用JMS ActiveMQ SpringBoot创建了持久订阅者。我还使用UUID.randomUUID()生成了惟一的客户机ID。toString()。然而,在启动订户(接收器)时,应用程序抛出以下警告消息 请帮我删除上述警告信息。 Receiver.java 学生.java SendMessageApplication.java 主题发送消息.java
我正在使用Hazelcast进行集群数据分发。我阅读了有关使用MapStore和MapLoader接口的数据持久性的文档。我需要实现这些接口,并在hazelcast中编写类名。xml文件。 有没有使用hazelcast实现这些文件持久性接口的示例?有人知道我可以下载和使用的任何源代码或jar文件吗? 谢谢
警告:容器被设计为无状态的实例,任何需要持久化的数据,请采用数据库或文件系统保存在容器实例之外,我们不对保存在容器内的数据提供任何保障。当 DaoCloud 需要迁移,或用户扩容容器资源时,容器内的数据将会遗失,并且无法找回。 使用数据库服务 DaoCloud 在服务集成模块中提供了 MySQL、Redis、MongoDB、InfluxDB 等数据服务,如您需要做内容的持久化保存,可以选择使用 M