[hibernate-issues] [Hibernate-JIRA] Created: (HHH-2341) ObjectNotFoundException on session.get() on non-existent object

Timo Thomas (JIRA) noreply at atlassian.com
Thu Jan 4 08:40:44 EST 2007


ObjectNotFoundException on session.get() on non-existent object
---------------------------------------------------------------

         Key: HHH-2341
         URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-2341
     Project: Hibernate3
        Type: Bug

  Components: core  
    Versions: 3.2.1    
 Environment: HSQLDB 1.8.0
    Reporter: Timo Thomas


Hibernate version:
3.2.1 GA (same for hibernate-annotations)

Mapping documents:

Parent.java (omitting package and some import declarations)


import javax.persistence.*;

@Entity   
public class Parent {

   public Integer id;
   public Set<Child> children = new HashSet<Child>();

   @Id
   @GeneratedValue(strategy = GenerationType.AUTO)
   public Integer getId() {
      return id;
   }

   public void setId(Integer id) {
      this.id = id;
   }

   @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL)
   public Set<Child> getChildren() {
      return children;
   }

   public void setChildren(Set<Child> children) {
      this.children = children;
   }
}


Child.java (omitting package and some import declarations)


import javax.persistence.*;

@Entity
public class Child {

   public Integer id;
   public Parent parent;
   
   @Id
   @GeneratedValue(strategy = GenerationType.AUTO)
   public Integer getId() {
      return id;
   }

   public void setId(Integer id) {
      this.id = id;
   }

   @ManyToOne(optional = false)
   @JoinColumn(name = "parent_fk")
   public Parent getParent() {
      return parent;
   }

   public void setParent(Parent parent) {
      this.parent = parent;
   }
}


Code between sessionFactory.openSession() and session.close():

       Transaction transaction = session.beginTransaction();
       
       Parent parent = new Parent();
       parent.setName("p1");
       session.persist(parent);
       assertNotNull(parent.getId());
       Integer parentId = parent.getId();

       Child child = new Child();
       child.setName("c1");
       child.setParent(parent);
       parent.getChildren().add(child);
       session.persist(parent);
       assertNotNull(child.getId());
       Integer childId = child.getId();

       transaction.commit();
       session.close();
       ///////////////////////////////////////////
       session = sessionFactory.openSession();
       transaction = session.beginTransaction();
       
       parent = (Parent) session.load(Parent.class, parentId);
       child = (Child) session.load(Child.class, childId);
//       child = (Child) session.get(Child.class, childId);
       session.delete(parent);
//       session.flush();   // !! required if session&transaction is re-opened and child is obtained with load(), otherwise exception on next line - BUG ?
       child = (Child) session.get(Child.class, childId);


Full stack trace of any exception that occurs:

org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [model.Child#1]
   at org.hibernate.impl.SessionFactoryImpl$1.handleEntityNotFound(SessionFactoryImpl.java:375)
   at org.hibernate.event.def.DefaultLoadEventListener.returnNarrowedProxy(DefaultLoadEventListener.java:223)
   at org.hibernate.event.def.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:187)
   at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:103)
   at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:878)
   at org.hibernate.impl.SessionImpl.get(SessionImpl.java:815)
   at org.hibernate.impl.SessionImpl.get(SessionImpl.java:808)
   at test.CascadeAnnotationTest.testBug(CascadeAnnotationTest.java:48)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
   at java.lang.reflect.Method.invoke(Method.java:585)
   at junit.framework.TestCase.runTest(TestCase.java:164)
   at junit.framework.TestCase.runBare(TestCase.java:130)
   at junit.framework.TestResult$1.protect(TestResult.java:110)
   at junit.framework.TestResult.runProtected(TestResult.java:128)
   at junit.framework.TestResult.run(TestResult.java:113)
   at junit.framework.TestCase.run(TestCase.java:120)
   at junit.framework.TestSuite.runTest(TestSuite.java:228)
   at junit.framework.TestSuite.run(TestSuite.java:223)
   at org.junit.internal.runners.OldTestClassRunner.run(OldTestClassRunner.java:35)
   at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:38)
   at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)

The generated SQL (show_sql=true):

Hibernate: insert into Parent (id, name) values (null, ?)
Hibernate: call identity()
Hibernate: insert into Child (id, name, parent_fk) values (null, ?, ?)
Hibernate: call identity()
Hibernate: select parent0_.id as id0_0_, parent0_.name as name0_0_ from Parent parent0_ where parent0_.id=?
Hibernate: select children0_.parent_fk as parent3_1_, children0_.id as id1_, children0_.id as id1_0_, children0_.name as name1_0_, children0_.parent_fk as parent3_1_0_ from Child children0_ where children0_.parent_fk=?


Why is this exception thrown under these circumstances? Am I using the API in an undocumented/disallowed way? If yes, where exactly? 

The Hibernate API doc says, that Session.get() returns null if an object can't be found. No exception should be thrown.

However, Session.get() at the end of sample code does return null as expected, if either

a) Session.get() is used instead of load() some lines above (see commented line)

b) the transaction and the session is isn't closed or reopened, respectively

c) Session.flush() is called before the final call to Session.get()

I'd like to understand why Hibernate behaves like this, which I presume is erroneous. I'm a beginner in Hibernate, but I couldn't get any help in the forum.

Timo

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://opensource.atlassian.com/projects/hibernate/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira




More information about the hibernate-issues mailing list