Как сохранить автоматически сгенерированное значение JPA перед коммитом? - PullRequest
0 голосов
/ 12 декабря 2010

Привет, я новичок в мире JPA, у меня вопрос по автоматически сгенерированному идентификатору.Мы используем OpenJPA. Мое приложение требует, чтобы одна операция, которая создает группу связанных объектов, была внутри одной транзакции, которая будет частью глобальной транзакции (XA).Я борюсь за получение автоматически сгенерированного идентификатора и использую его для установки значений в другом объекте.Вот снимок:

@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 будет использовать неуправляемую передачу.Теперь проблема может заключаться в следующем: всякий раз, когда вызывается getId, он возвращает новое значение, а когда окончательный отдел сохраняется, идентификатор является последним номером, поэтому все другие объекты ссылаются на несуществующий отдел.Есть ли способ справиться с этим, чтобы идентификатор (kindof) сохранялся?

У меня есть свободное решение для требований, которое сначала создаст фиктивный отдел и сохранит его, поэтому идентификатор не изменится.Код похож на этот:

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() заблокирует строку БД.

Пожалуйста, дайте мне несколько идей о том, как ее решить.

Спасибо, Говард.

1 Ответ

3 голосов
/ 12 декабря 2010

Я не до конца понимаю вашу проблему, но я думаю, что вместо того, чтобы указывать DepartmentId в вашем классе преподавателей, вы должны установить вместо этого Department, т.е.

 void setDepartmentId(long id);

изменить на

 void setDepartment(Department d);

Компоненты id должны автоматически обрабатываться менеджером объекта

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...