java – org. hibernate. Objectnotfoundexception: no row with the given identifier exists
Since hibernate 4.1 Since August 8, I have had a problem, resulting in the following exceptions:
org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [test.hibernate.TestPrepravkaOsobaSAdresou$Uvazek#2]
I have a simple onetomany association between two entities:
@Entity(name = "Ppv") @Table(name = "PPV") public static class Ppv { @Id Long ppvId; @OneToMany(fetch = FetchType.EAGER,mappedBy = "ppv") Set<Uvazek> uvazeks = new HashSet<Uvazek>(0); } @Entity(name = "Uvazek") @Table(name = "UVAZEK") public static class Uvazek { @Id Long uvazekId; @ManyToOne @JoinColumn(name = "PPV_FXID") Ppv ppv; }
And a test case, I have a PPV and two uvazek When I load and detach a PPV, delete a uvazek associated with loading PPV and merge PPV, I get an exception
jdbcTemplate.execute("insert into PPV values(1)"); jdbcTemplate.execute("insert into UVAZEK values(2,1)"); jdbcTemplate.execute("insert into UVAZEK values(3,1)"); Ppv ppv = (Ppv) getSession().get(Ppv.class,1l); getSession().clear(); getSession().delete(getSession().get(Uvazek.class,2l)); getSession().flush(); getSession().merge(ppv); getSession().flush(); //Causes the exception
During PPV merge, hibernate attempts to load the deleted uvazek Even if uvazek is deleted, hibernate still has information about it
org.hibernate.collection.internal.AbstractPersistentCollection.storedSnapshot
The uvazek is set at the separated PPV This was valid in previous versions (< 4.1.8) In this simple example, I can fix it by adding orphanremoval = true to the uvazeks set on PPV, instead of removing uvazek from the uvazeks set on PPV So my question is: is this a hibernate error or my bad habit?
Solution
The problem is trying to merge uvazek with id = 2 Hibernate sees that it has a key, but it does not know whether the object is dirty, so it is not clear whether SQL update should be performed
However, because the key is 2, hibernate knows that the object must exist in the database, so it tries to load the object to compare it with the version just received in memory to see if the object has some pending changes synchronized with the database
However, select does not return any results, so hibernate has contradictory information: on the one hand, the database indicates that the object does not exist On the other hand, an object in memory means that the object must exist with key 2 Unable to determine which object is correct, an objectnotfoundexception exception is thrown
What happened? Before this release, the code was accidentally based on a bug that was fixed at the same time, so it no longer works
The best practice is to avoid clearing. It can only be used when memory optimization is required. Just clear the objects that are no longer modified or needed in the same session, and then look at is session clear() considered hammful