From: Georg S. <ge...@sc...> - 2002-02-12 12:41:16
|
cirrus.hibernate.impl.RelationalDatabaseSession.find() recurse indefinitely, if the id of the object can't be found (resulting in a StackOverflowException). The check, if the object is succesfully retrieved, is performed _after_ the recursion and so is never executed. To fix this, line 559 ("if (!success) throw new...") has to be moved to 553 (after "deferLoads--;" and _before_ "if (deferLoads==0 ..."), resulting in the folowing: 551 deferLoads--; 552 553 if (!success) throw new HibernateException("id not found or provided object was wrong class"); 554 555 // now actually load the state into all the waiting objects... 556 // this code is _not_ executed recursively 557 if (deferLoads==0) doDeferredLoads(); 558 559 doLoadCallbacks(results, cols); Here is a test for the code above, I think it only works with mysql, because other dbms have support for foreign key constraints and will delete Glarch g if I delete Glarch g2. I am right? protected void testIdNotFound(SessionFactory sessions) throws Exception { //The following test is only enabled for MySQL which has no foreign key constraints. if (db.equals("mysql")) { Session s = sessions.openSession(); Glarch g = (Glarch) s.create(Glarch.class); Glarch g2 = (Glarch) s.create(Glarch.class); g.setNext(g2); Serializable gid = s.getID(g); Serializable g2id = s.getID(g2); s.commit(); s = sessions.openSession(); g2 = (Glarch) s.load( Glarch.class, g2id ); s.delete(g2); s.commit(); s = sessions.openSession(); boolean ok = false; try { g = (Glarch) s.load( Glarch.class, gid ); } catch (HibernateException e) { ok = "id not found or provided object was wrong class".equals(e.getMessage()); } catch (java.lang.StackOverflowError soe) { ok = false; } assert( ok, "id not found"); s.commit(); } } P.S.: build.xml lacks the exclusion of the build directory and the build.xml file. If you are lazy and build without doing "ant clean" before, the build-directory is recursively copied in the build-directory ... The two exclude Tags fix it: 32 <patternset id="support.files"> 33 <include name="**/*.properties"/> 34 <include name="**/*.dtd"/> 35 <include name="**/*.xml"/> 36 <exclude name="build/**/*"/> 37 <exclude name="build.xml"/> 38 </patternset> |