【发布时间】:2017-09-20 09:39:04
【问题描述】:
我使用 Wildfly 作为我的 Java EE 服务器。我们有一个框架用于实现某种命令设计模式。
我将尽可能简单地描述工作流程:
- 每个命令都是一个实体,用于存储有关命令的信息(执行时间戳、成功状态等)
- 每个命令都有它的 CommandEJB,在其中执行业务逻辑
- 我们所有的命令都扩展自 Command 类,它们的 EJB 扩展自 CommandEJB 类
- CommanEJB 调用 run 方法,该方法被特定命令覆盖,其中为该特定命令执行业务逻辑
- 之后,CommandEJB 尝试持久化 Command 对象(该对象携带有关命令执行的信息,如第 1 点所述)
- 如果 CommandEJB 实现正在创建一个实体并将其持久化到它的 run 方法的实现中,那么我们总是会在特定命令和该实体之间建立双向关联
我会尝试写一些伪代码来解释它是如何工作的:
我有一个名为 Person 的实体,我有一个 CreatePersonCmd 命令,它应该创建一个新人并将其保存到数据库中。之后,框架将 CreatePersonCmd 持久化到数据库中。在命令执行时,Person 实体和 CreatePersonCmd 实体通过
链接person.setCmd(cmd); 和
cmd.setPerson(person);
我有一个调用命令的 SAOP Web 服务:
@Stateless
@WebService
public class MyWebService {
CreatePersonCmd cmd = new CreatePersonCmd();
executor.execute(cmd);
}
我的 CreatePersonCmd 是 CreatePersonCommand 和 Person 之间关系的所有者,如下所示:
public class CreatePersonCmd {
@JoinColumn
@OneToOne
private Person person;
}
关系的另一边是人:
public class Person{
@OneToOne(mappedBy="person")
private CreatePersonCmd createPersonCmd;
}
在我的 CreatePersonEJB(调用其 run 方法实现)中:
public class CreatePersonCmdEJB extends CommandEJB {
public void run() {
Person person = new Person("John Doe");
createPersonCmd.setPerson(person);
person.setCreatePersonCmd(createPersonCmd);
em.persist(person);
}
之后,CommandEJB 继续执行并尝试保存命令:
em.persist(createPersonCmd);
但是,执行永远不会到达最后一行,并且我在以下位置遇到异常:
em.persist(person);
例外是:
Not-null property references a transient value - transient instance must be saved before current operation
奇怪的是,如果我让 Person 成为关系的所有者,那么一切正常。
我做了一个简单的例子,没有我们的框架,它有 2 个实体 Customer 和 Address,它们也有双向 OneToOne 关系,但是我做测试它总是提交很好,无论我使用什么持久化顺序。
这是伪代码:
Customer c = new Customer("John Doe");
Address a = new Address("MyStreet", 1123);
c.setAddress(a);
a.setCustomer(c);
em.persist(c);
em.persist(a);
无论持久化的顺序是什么(地址或客户优先,如果我有两条线,它总是可以提交)
但是,在我们的框架中,似乎事务在 em.persist(person) 之后结束,我在框架源代码中没有看到 em.flush()。
有什么方法可以知道我是否在同一个事务中? 我试图通过em.getTransaction() 获取事务,但我得到了A JTA EntityManager cannot use getTransaction(),可能是因为 Java EE 中的事务是由应用程序容器管理。
【问题讨论】:
-
em.isJoinedToTransaction()应该告诉您em是否与活动事务相关联。
标签: java hibernate jpa jakarta-ee jta