2010-12-12 2 views
0

Привет, я новичок в мире JPA, у меня есть вопрос об автогенерированном id. Мы используем OpenJPA, мое приложение требует, чтобы одна операция, которая создавала кучу связанных объектов, должна находиться внутри одной транзакции, которая будет частью глобальной транзакции (XA). Я пытаюсь получить автоматически генерируемый идентификатор и использовать его для установки значений в другом объекте. Вот снимок:Как сохранить автогенерированное значение 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 (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); 
    } 

Теперь я не знаю, как я могу установить Тй для removeEmptyDepartment(), если требуется, он будет использовать глобальный запрос, так что будет откатить, а также. Если это новый tx, это вызовет тупик, так как reallyDoSomething() заблокирует строку db.

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

Thanks, Howard.

+0

У вас есть аннотация @Id? – Koitoer

ответ

3

Я не полностью понимаю ваш вопрос, но я думаю, что вместо установки DepartmentID в классе профессора, вы должны быть настройки Департамент вместо т.е.

void setDepartmentId(long id); 

изменение

void setDepartment(Department d); 

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

+0

Спасибо. Это очень поможет. Однако не все подпрограммы являются только ссылкой на сущность. Например, есть отправка сообщения JMS (который использует тот же XA tx), который также вызывает этот getId(). –

Смежные вопросы