[英]Is there any way to tell if a new transaction is started in JTA
我將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;
}
關系的另一面是Person:
public class Person{
@OneToOne(mappedBy="person")
private CreatePersonCmd createPersonCmd;
}
在我的CreatePersonEJB(調用其運行方法實現)中:
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中的事務由應用程序容器管理。
如果已經插入createPersonCmd,則必須將其添加到當前工作集中。 那可以通過
createPersonCmd = em.merge(createPersonCmd)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.