Jpa 添加实体和持久化单元后,EJB计时器服务不再可用
我正在玩弄EJB计时器,但在同一个项目中尝试同时运行计时器和持久性实体时遇到了麻烦。在我的初始设置中,我只有计时器,这些计时器按预期启动:Jpa 添加实体和持久化单元后,EJB计时器服务不再可用,jpa,jakarta-ee,timer,payara,Jpa,Jakarta Ee,Timer,Payara,我正在玩弄EJB计时器,但在同一个项目中尝试同时运行计时器和持久性实体时遇到了麻烦。在我的初始设置中,我只有计时器,这些计时器按预期启动: @Stateless public class TimerHandler { @Resource protected TimerService mTimerService; @PostConstruct public void init() { // could do cool stuff but choo
@Stateless
public class TimerHandler {
@Resource
protected TimerService mTimerService;
@PostConstruct
public void init() {
// could do cool stuff but choose not to
}
public Timer start(long aDuration) {
TimerConfig conf = new TimerConfig();
conf.setPersistent(false); // don't want the timer to be saved
return mTimerService.createSingleActionTimer(aDuration, conf);
}
@Timeout
public void timeOutAction(Timer aTimer) {
// does fancy stuff
System.out.println("So fancy :)");
}
}
我在让计时器运行时遇到了一些麻烦,但我采取了粗暴的方式重新安装了Payara(Glassfish)。在这之后,使用计时器就可以了。我可以启动并取消它,如下所示:
@Stateful
public class MyClass {
@EJB
private TimerHandler mTimerHandler;
private Timer mTimer;
public void startTimer(int aDuration) {
mTimer = mTimerHandler.start(aDuration);
}
public void stopTimer() {
try {
mTimer.cancel();
} catch (NoSuchObjectLocalException | NullPointerException ex) {
System.out.println("There is no timer running.");
}
}
}
然而,在我尝试将实体添加到项目中之后,问题出现了。我的实体如下所示:
@Entity
public class TestEntity implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String testValue;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTestValue() {
return testValue;
}
public void setTestValue(String value) {
testValue = value;
}
// removed standard code for @Override of equals(),
// hashCode() & toString()
}
我通过我的控制器bean操纵它:
@Stateless
public class TestDBController {
@PersistenceContext(unitName = "TimerTestWithDBPU")
private EntityManager em;
public long saveValue(String value) {
TestEntity entity = new TestEntity();
entity.setTestValue(value);
em.persist(entity);
em.flush();
return entity.getId();
}
public String getValue(long aId) {
TestEntity entity = em.find(TestEntity.class, aId);
return entity.getTestValue();
}
}
我的持久性单元(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="TimerTestWithDBPU" transaction-type="JTA">
<jta-data-source>jdbc/timer_test_pool</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="javax.persistence.schema-generation.database.action"
value="create"/>
</properties>
</persistence-unit>
</persistence>
为什么会这样?您不能同时使用ejb计时器和持久实体运行应用程序吗?事实证明,您可以!谁会想到 这句来自《圣经》的话为我指明了正确的方向 使用EJB计时器服务相当于与单个JDBC资源管理器交互。如果EJB组件或应用程序直接通过JDBC或间接(例如,通过实体bean的持久化机制)访问数据库,并且还与EJB计时器服务交互,则其数据源必须配置XA JDBC驱动程序 我将尝试描述我所做的工作(我是JavaEE领域的新手,因此一些概念和特性名称可能不正确) 在我的例子中,您需要在应用程序服务器(Payara)中配置一个资源,以便它使用XA JDBC驱动程序而不是普通的JDBC驱动程序。(我不完全理解为什么会这样,如果有人愿意详细说明,我很乐意听到) 为此:
- 一个名字,在我的例子中是“TestPool”
- 选择资源类型为:“javax.sql.XADataSource”
- 选择您的供应商:我使用JavaDB
- 服务器名(如localhost)
- 端口号(如1527)
- 密码(如测试)
- 用户(如测试)
- URL(例如jdbc:derby://localhost:1527/Test)
- 数据库名称(如测试)
%install-path-of-payara%\glassfish\lib\install\databases\
选择文件ejbtimer\u[VENDOR\u NAME].sql,并在您创建的数据库上运行该文件。在此之后,您应该将其作为ejb计时器的默认连接工具。在Payaras管理页面:
希望这对某人有所帮助:)由于您使用的是非持久计时器,这可能是Payara/Glassfish中的一个bug。非持久化计时器不应该需要数据源。如果可以的话,尝试使用fresh Payara Web Profile分发版,看看计时器是否可以开箱即用(Web Profile根本不支持持久计时器,因此不需要计时器的数据源)。
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="htt...>
<persistence-unit name="TimerTestPU" transaction-type="JTA">
<jta-data-source>jdbc/TestPool</jta-data-source> <!-- Magic Line -->
.
.
.
</persistence-unit>
</persistence>
java.lang.NoClassDefFoundError: Could not initialize class
org.apache.derby.jdbc.EmbeddedDriver Could not initialize class
org.apache.derby.jdbc.EmbeddedDriver
%install-path-of-payara%\glassfish\lib\install\databases\