2

What I'm doing is just creating one Object and trying to save it to the database.

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

this is the entity class:

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

What happens... :

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

The object is created in the database and the transaction ends but on refresh(o) the Entity manager is querying O where id=0 but the O id is auto incremented to some value that is not 0. So query by 0 is returning nothing and EntityNotFoundException is thrown. Why refresh is searching for object with id 0? May be the object o is not updated in the cache and the EntityManager still thinks that this object is with id 0;

makkasi
  • 6,328
  • 4
  • 45
  • 60

1 Answers1

3

The ID is autogenerated by the database. But JPA doesn't know anything about it, since you haven't told it. So it assumes that the ID of the entity is the one it had when calling persist(): 0.

You have to tell JPA that the database generates the ID:

@GeneratedValue(strategy = IDENTITY)
private int id;

That way, after JPA has inserted the row in the database, it will ask the database for the generated key, and assign it to the ID. Your refresh will thus be useless.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255