prabello
prabello

Reputation: 556

javax.persistence.EntityNotFoundException: Unable to find object with id X

I'm trying to persist an object, after that i want to add 2 lists to that object and then update it (Since i can't persist the object with the lists).

All beign done inside a loop, the first iteration works just fine, from the second i get a EntityNotFoundException saying that the ID wasn't found to do the update.

private Foo foo;
private FooDao dao;

for(int i = 0 ; i<10 ; i++){
  foo = new Foo();
  foo.setVar(i);

  dao.save(foo);

  generateLists(); //creates a new list every interaction 
  foo.setCatList(catList);
  foo.setBarList(barList);

  dao.update(foo);
}

If i remove the Lists and the update it works fine.

The object:

@Entity
public class Foo {

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  @Basic(optional = false)
  private Integer id;

  @Basic(optional = false)
  @NotNull
  private String var;

  @OneToMany(cascade = CascadeType.ALL)
  private List<Bar> barList;

  @OneToMany(cascade = CascadeType.ALL)
  private List<Cat> catList;

  //Getters and Setters
}

The DAO methods:

public void save(Foo foo) {
  this.manager.joinTransaction();
  this.manager.persist(foo);
  //this.manager.flush(); Tried this, but didn't work
}

public void update(Foo foo) {
  this.manager.joinTransaction();
  this.manager.merge(foo);
}

The error:

ERROR [org.jboss.as.ejb3] (EJB default - 1) javax.ejb.EJBTransactionRolledbackException: Unable to find foo with id 4
ERROR [org.jboss.as.ejb3.invocation] (EJB default - 1) JBAS014134: EJB Invocation failed on component FooDao for method public void FooDao.atualiza(Foo): javax.ejb.EJBTransactionRolledbackException: Unable to find Foo with id 4

ps: Using this generic approach to simplify, if needed i'll post my solution(or the mess that i call solution)

Upvotes: 3

Views: 31531

Answers (4)

Shahid Hussain Abbasi
Shahid Hussain Abbasi

Reputation: 2692

Adding this:

@NotFound(action = NotFoundAction.IGNORE)

with @ManyToOne or @OneToOne is helpful because ...ToOne is FetchType.EAGER by default.

Upvotes: 2

Taraskin
Taraskin

Reputation: 792

I got similar issue. Fixed by updating @ManyToOne annotation to:

    @NotNull
    @JoinColumn(nullable = false)
    @ManyToOne(optional = false, fetch = FetchType.LAZY)
    private ParentEntityClass parent;

added: nullable = false, optional = false, fetch = FetchType.LAZY and, in addition to these - @NotNull (javax.validation.constraints.NotNull - probably not necessary, just to prevent null-ables :) )

Upvotes: 0

Koitoer
Koitoer

Reputation: 19533

I believe problem is with the transactions obtain the transaction and commit within the save method in your dAO.

this.manager.getTransaction().commit();

If an error comes it is because there is no active transaction it is why the flush fails. Be sure you are within a transaction, consider use EntityTransaction to begin , commit and end the transaction around your DAO methods.

If you don't have an active TX you won't be able to write entities to the database, and when you try to merge something the entity won't be found then this is the reason for what you are getting EntityNotFoundException

--- UPDATE

When you do the merge, what is the ID that the Foo object have ? I believe is not the correct one , or at least the last id inserted in the database, so what I suggest is find first and then merge.

Use

<T> T find(java.lang.Class<T> entityClass,
           java.lang.Object primaryKey)

Using the id, and verify the instance have the correct key

Upvotes: 0

singhakash
singhakash

Reputation: 7919

Because you are adding same lists again and again.Since you have OneToMany the second transaction says you already persisted that list.

An workaround would to change relation to ManyToMany

Upvotes: 2

Related Questions