em.refresh(o)上的'EntityNotFoundException:实体不再存在于数据库'

时间:2014-08-15 13:11:03

标签: jpa

我正在做的只是创建一个Object并尝试将其保存到数据库中。

 public O create(O o) {
        em.getTransaction().begin();
        em.persist(o);
        em.getTransaction().commit();
        em.refresh(o);
        return o;
    }

这是实体类:

@Entity
@Table(name = "o")
public class O implements Serializable {
    private static final long serialVersionUID = 1L;

    private int id;

    @ManyToOne(cascade=CascadeType.REFRESH, fetch = FetchType.LAZY)
    @JoinColumn(name = "b_id")
    private B b;

    @OneToMany(fetch = FetchType.EAGER ,  cascade = CascadeType.ALL)
    @JoinTable(name="o_p", 
    joinColumns=@JoinColumn(name="o_id", referencedColumnName="id"),
    inverseJoinColumns=@JoinColumn(name="p_id", referencedColumnName="id"))
    private List<P> p; 

会发生什么......:

DataService<O> das = new ODataService();
O o = new O();
das.create(O);

在数据库中创建对象并且事务结束但在刷新(o)时,实体管理器正在查询O,其中id = 0但是O id自动递增到某个非0的值。因此,查询0是什么都不返回,抛出EntityNotFoundException。为什么刷新是在搜索id为0的对象?可能是对象o未在缓存中更新,并且EntityManager仍然认为此对象的ID为0;

1 个答案:

答案 0 :(得分:3)

ID由数据库自动生成。但JPA对此一无所知,因为你没有告诉它。因此,它假定实体的ID是它在调用persist()时所具有的ID:0。

您必须告诉JPA数据库生成ID:

@GeneratedValue(strategy = IDENTITY)
private int id;

这样,在JPA在数据库中插入行之后,它将向数据库询问生成的密钥,并将其分配给ID。因此,您的刷新将毫无用处。