2010-12-12 52 views
0

嗨我是JPA世界的初學者,我對自動生成的ID有個疑問。我們使用的是OpenJPA,我的應用程序要求創建大量相關對象的一個​​操作必須位於單個事務中,該事務將成爲全局事務(XA)的一部分。我在努力獲取自動生成的id並使用它來設置其他對象中的值。這裏是快照:如何在提交之前保留JPA自動生成的值?

@ENTITY 
@Table(name="TDepart") 

class Department{ 

    private long id; 

    @GeneratedValue(strategy= GenerationType.TABLE) 

    public long getId(); 

} 

//And some classes like 

class Professor { 
    void setDepartmentId(long id); 
} 

Now I have a business operation: 

void doSomething() 
{ 

    Department depart = new Department(); 

    handleProfessors (depart); 
    handleStudent (depart); 
    //and someother rountines need to refer department 
} 

//sample code which will getId 
void handleProfessors(Department depart) 
{ 

    Professor p = new Professor(); 

    p.setDepartmentId(depart.getId); 

} 

所以Department.getId()會被多次調用。 doSomething()將處於單個託管事務中,但GeneratedValue將使用非託管tx。現在可能的問題是:每當getId被調用時,它將返回一個新的值,並且當部門最終持久化時,id是最新的數字,因此所有其他對象都指向一個不存在的部門。無論如何要處理這個,以便id(kindof)堅持?

我有一個寬鬆的需求解決方案,它將首先創建一個虛擬部門並堅持它,所以ID不會改變。該代碼與此類似:

void doSomething() 
{ 
    Department depart = createEmptyDepartment(); // always new tx so department is created; 

    try { 
    reallyDoSomehing(); // tx required so it is part of global tx 
    } 
    catch (SomeException e) { 
    removeEmptyDepartment(depart); 
    } 

現在我不知道我怎麼可以設置爲TX removeEmptyDepartment(),如果需要,將利用全球的要求,因此也會被回滾。如果它是新的tx,它將導致死鎖,因爲reallyDoSomething()將鎖定db行。

請給我一些關於如何解決它的想法。

謝謝, 霍華德。

+0

您是否有@Id註釋? – Koitoer 2014-02-01 01:15:22

回答

3

我不完全理解你的問題,但我在想,而不是你的教授級設置DepartmentID的,你應該在系部設置,而不是 即

void setDepartmentId(long id); 

變化

void setDepartment(Department d); 

id組件應該由實體管理器自動處理

+0

謝謝。這將有很大幫助。然而並非所有例程都只是實體引用。例如,有一個JMS消息發送(它使用相同的XA tx),它也調用此getId()。 – 2010-12-12 18:51:19

相關問題