我使用Wildfly作为我的Java EE服务器。我们有一个框架,我们用它来实现一种命令设计模式。
我会尝试尽可能简单地描述工作流程:
我会尝试编写一些伪代码来解释它是如何工作的:
我有一个名为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);
无论持久性的顺序是什么(地址或客户优先,如果我有两条线,它总是很好)
然而,在我们的框架中,似乎tra.actions在em.persist(person)之后结束,我在框架源代码中看不到em.flush()。
我是否有任何方式可以知道我是否在同一笔交易中?我试图通过em.getTransaction()
获取交易,但我得到A JTA EntityManager cannot use getTransaction()
,可能是因为转换在Java EE中由应用程序容器管理。
答案 0 :(得分:0)
如果已插入createPersonCmd,则必须将其添加到当前工作集。 这可以通过
来完成createPersonCmd = em.merge(createPersonCmd)