2010-12-12 59 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

相关问题