【问题标题】:Is there any way to tell if a new transaction is started in JTA有什么方法可以判断 JTA 中是否启动了新事务
【发布时间】: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


【解决方案1】:

如果 createPersonCmd 已插入,则必须将其添加到当前工作集。 这可以通过

createPersonCmd = em.merge(createPersonCmd)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-30
    • 2021-10-22
    • 2014-04-18
    • 2023-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多