JavaEE JPA 同步对象与数据库

JavaEE JPA synchronise object with database

我有一个用户 class 和一个电子邮件 class。 我使用@OneToMany annotatioin 来描述一个用户可以有很多电子邮件并且一个电子邮件被分配给一个用户的关系。

现在的问题是:在创建用户和电子邮件并将电子邮件分配给用户时,我试图找到一种方法让 JPA 初始化电子邮件集。通常这在我做 em.find(User.class, "test"); 时工作正常 这仅在我创建用户时不起作用。 emails 属性的大小始终为 0 甚至为空。但是当我创建一个用户,然后重新部署我的应用程序并执行 em.find(User.class, "test") 时,电子邮件属性被正确设置为 1,我可以访问它。

@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("test@test.com");
e.setUser(user);
em.persist(e);

return user;

执行这些语句后,用户属性emails为空(很明显)。但奇怪的是,当我用另一种方法执行 em.find(User.class, "test"); 时,emails 属性的大小为 0,即使记录已正确插入数据库。 当我现在重新部署我的应用程序并再次调用 em.find(User.class, "test"); 时,emails 属性的大小为 1。 我已经尝试调用 em.merge();em.refresh(); 但没有用。 我正在使用 glassfish 4.1.1。作为事务类型,我将 JTA 和 eclipselink 用于 JPA 实现

您需要设置任何双向关系的两边,JPA 不会为您做。如果你不这样做,未设置的一面将不会反映数据库中的内容,直到它来自数据库 reloaded/refreshed 。您可以使用 em.refresh(user) 强制刷新,但通常最好避免数据库命中并仅将电子邮件添加到用户的电子邮件列表中。

您还需要将电子邮件添加到 Usermerge 用户(如果您分两步进行),或者(您可能需要 cascade=CascadeType.ALL)只需将其放在 User 开头,如果您一步完成,则将其放在 persist User 中。

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("test@test.com");
e.setUser(user);

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

return user;