2016-03-10 1 views
1

J'ai une classe User et une classe Email. J'ai utilisé l'annotation @OneToMany pour décrire une relation qu'un utilisateur peut avoir plusieurs e-mails et qu'un e-mail est assigné à un utilisateur.JavaEE JPA synchronise l'objet avec la base de données

Maintenant, le problème est le suivant: lors de la création d'un utilisateur et d'un e-mail et de l'attribution de l'e-mail à l'utilisateur, j'essaie de trouver un moyen d'initialiser l'ensemble d'e-mails. Habituellement, cela fonctionne bien quand je fais em.find(User.class, "test"); Cela ne fonctionne pas lorsque je crée un utilisateur. L'attribut emails est toujours de taille 0 ou même nulle. Mais lorsque je crée un utilisateur, puis redéployez mon application puis exécutez em.find(User.class, "test"), l'attribut emails est correctement défini de taille 1 et je peux y accéder.

@Entity 
public class User implements Serializable { 
    private String username; 
    private String password; 
    private Set<Email> emails; 

    @OneToMany(mappedBy = "user", fetch = FetchType.EAGER) 
    public Set<Email> getEmails() { 
     return emails; 
    } 

    public void setEmails(Set<Email> emails) { 
     this.emails = emails; 
    } 

    @Id 
    @Column(name = "Username") 
    public String getUsername() { 
     return username; 
    } 

    public void setUsername(String username) { 
     this.username = username; 
    } 

    @Basic 
    @Column(name = "Password") 
    public String getPassword() { 
     return password; 
    } 

    public void setPassword(String password) { 
     this.password = password; 
    } 

-

@Entity 
public class Email implements Serializable { 
    private int id; 
    private String email; 
    private User user; 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    @Column(name = "Id") 
    public int getId() { 
     return id; 
    } 

    public void setId(int id) { 
     this.id = id; 
    } 

    @ManyToOne 
    @JoinColumn(name = "user") 
    public User getUser() { 
     return user; 
    } 

    public void setUser(User user) { 
     this.user = user; 
    } 

    @Basic 
    @Column(name = "Email") 
    public String getEmail() { 
     return email; 
    } 

    public void setEmail(String email) { 
     this.email = email; 
    } 

-

User user = new User(); 
user.setUsername("test"); 
user.setPassword("asdf"); 
em.persist(user); 

Email e = new Email(); 
e.setEmail("[email protected]"); 
e.setUser(user); 
em.persist(e); 

return user; 

après l'exécution de ces déclarations, l'attribut utilisateur emails est nul (évidemment). Mais étrangement quand je fais em.find(User.class, "test"); dans une autre méthode, l'attribut emails est de taille 0, même si les enregistrements sont correctement insérés dans la base de données. Lorsque je redéploie maintenant mon application et appelez à nouveau em.find(User.class, "test");, l'attribut emails est de taille 1. J'ai déjà essayé d'appeler em.merge(); ou em.refresh(); qui ne fonctionnait pas. J'utilise le verre de verre 4.1.1. Comme type de transaction, j'utilise JTA et eclipselink pour l'implémentation JPA

Répondre

1

Vous devez ajouter le courrier électronique à l'User ainsi et merge l'utilisateur si vous le faites en deux étapes, ou (vous devrez peut-être en cascade = CascadeType.ALL) il suffit de mettre dans le User pour commencer et persist le User si vous le faites en une seule étape.

User user = new User(); 
Set<Email> emails = new HashSet<Email>(); 
user.setEmails(emails); 
user.setUsername("test"); 
user.setPassword("asdf"); 

Email e = new Email(); 
e.setEmail("[email protected]"); 
e.setUser(user); 

emails.add(e); 
em.persist(user); 

return user; 
0

Vous devez définir les deux côtés de toute relation bidirectionnelle, JPA ne le fera pas pour vous. Si vous ne le faites pas, le côté désactivé ne reflétera pas ce qui se trouve dans la base de données tant qu'il n'a pas été rechargé/actualisé à partir de la base de données. Vous pouvez forcer l'actualisation en utilisant em.refresh (utilisateur), mais il est généralement préférable d'éviter l'accès à la base de données et d'ajouter simplement l'e-mail à la liste des e-mails de l'utilisateur.