1

我正在尝试使用 EclipseLink 保存一个名为 Stat 的对象。如果 id 存在于数据库中,则更新该对象。如果没有,请创建一个新对象。这是我的对象:

@Entity
public class Stat {

    @Column
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    public long id;

    @JoinColumn
    @ManyToOne
    public User user;


    @Column
    public boolean accepted;

    @Column
    public boolean finished;

    public Stat() {
    }
}

这是我添加/更新对象的方法。

public long addReplaceStat(Stat stat) {
            em.getTransaction().begin();
            Stat oldStat = em.find(Stat.class, stat.id);
            if (oldStat == null)
                em.persist(stat);
            else
                em.merge(stat);
            em.getTransaction().commit();

            em.getTransaction().begin();
            Stat newStat = em.find(Stat.class, stat.id);
            if (newStat != null)
                em.refresh(newStat);
            em.getTransaction().commit();

            return stat.id;
        }

我的问题是我在 em.refresh() 处遇到异常,说“类 [User] 的属性 [id] 已映射到数据库中的主键列。不允许更新。” 我不明白为什么。不应该刷新只是更新我的托管对象的值而没有问题吗?

做我想做的事(添加或更新)的最佳习语是什么?

4

1 回答 1

3

JPA 规范说:

应用于实体 X 的合并操作的语义如下:

  • 如果 X 是分离实体,则 X 的状态被复制到具有相同身份的预先存在的受管实体实例 X' 上,或者创建 X 的新受管副本 X'。
  • 如果 X 是一个新的实体实例,则创建一个新的托管实体实例 X',并将 X 的状态复制到新的托管实体实例 X'。

[...]

因此,要添加如果不存在或更新是否存在,您只需要执行以下操作:

Stat attachedStat = em.merge(stat);

关于您的刷新问题,我不知道为什么会发生。但是为什么要刷新刚刚从数据库中加载的实体呢?没有什么可刷新的。

于 2012-11-04T12:38:38.810 回答