如何在提交之前保留JPA自动生成的值?

时间:2010-12-12 08:25:04

标签: java jpa

您好我是JPA世界的初学者,我对自动生成的ID有疑问。我们正在使用OpenJPA,我的应用程序要求创建一堆相关对象的一个​​操作必须在单个事务中,这将成为全局事务(XA)的一部分。我正在努力获取自动生成的id并使用它来设置其他对象中的值。这是快照:

@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);
  }

现在我不知道如何设置removeEmptyDepartment()的tx,如果需要它将使用全局请求,因此它也将回滚。如果它是新的tx,它将导致死锁,因为reallyDoSomething()将锁定db行。

请给我一些关于如何解决它的想法。

谢谢, 霍华德。

1 个答案:

答案 0 :(得分:3)

我不完全理解你的问题,但我想的是你应该设置部门,而不是在教授课程中设置departmentId。 即。

 void setDepartmentId(long id);

更改为

 void setDepartment(Department d);

id组件应由实体管理器自动处理