2010-12-12 5 views
0

Salut, je suis débutant sur le monde JPA, j'ai une question sur l'ID généré automatiquement. Nous utilisons OpenJPA, Mon application nécessite qu'une opération qui crée un tas d'objets liés doit être à l'intérieur d'une seule transaction qui fera partie de la transaction globale (XA). J'ai du mal à obtenir l'identifiant généré automatiquement et l'utiliser pour définir des valeurs dans un autre objet. Voici l'instantané:Comment conserver une valeur générée par JPA générée avant la validation?

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

} 

Ainsi, Department.getId() sera appelé plusieurs fois. Le doSomething() sera dans une seule transaction gérée, mais GeneratedValue utilisera un tx non géré. Le problème est peut-être: chaque fois que le getId est appelé, il retourne une nouvelle valeur, et lorsque le département est final, l'identifiant est le dernier numéro, donc tous les autres objets se réfèrent à un département inexistant. Y at-il de toute façon gérer cela pour que l'id soit (kindof) persister?

J'ai une solution d'exigence lâche, ce qui créera d'abord un département factice et le persistera, de sorte que l'ID ne change pas. Le code est similaire à ceci:

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

Maintenant, je ne sais pas comment je peux régler le tx pour removeEmptyDepartment(), si nécessaire, il utilisera la demande mondiale il sera rollback aussi bien. Si c'est un nouveau tx, cela provoquera un blocage puisque reallyDoSomething() verrouillera la ligne db.

S'il vous plaît, donnez-moi quelques idées sur la façon de le résoudre.

Merci, Howard.

+0

Avez-vous des annotations @Id? – Koitoer

Répondre

3

Je ne comprends pas bien votre question, mais je pense que, plutôt que de mettre l'departmentId dans votre classe de professeur, vous devez régler le Département à la place -à-dire

void setDepartmentId(long id); 

changement

void setDepartment(Department d); 

Les composants id doivent être gérés automatiquement par le gestionnaire d'entités

+0

Merci. Cela aidera beaucoup. Cependant, toutes les routines ne sont pas seulement des références d'entités. Par exemple, il y a un envoi de message JMS (qui utilise le même Xx tx) qui appelle aussi getId(). –

Questions connexes