Hi all.
Something strange happen to my application.
Suppose you have a Test class with an integer primary key.
Than suppose to perform the following steps:
1) search for a non-existent instance with key value 1 (integer)
2) Obviously, you get an ObjectNotFoundException...
3) Insert an instance with key 1
4) search for the instance with key 1 : now you should find it!!
5) Why do I still get ObjectNotFoundException???
It seems that the session 'caches' the ObjectNotFoundException.
Infact, if I search for instances that didn't fail before, the session can successfully find them.
The output of the attached code should be:
====
Test with key 2 : TEST STRING FOR KEY WITH VALUE 2
Test with key 1 : TEST STRING FOR KEY WITH VALUE 1
====
Actually I get:
====
Test with key 2 : TEST STRING FOR KEY WITH VALUE 2
WHY???
org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [it.test.Test#1]
at org.hibernate.impl.SessionFactoryImpl$2.handleEntityNotFound(SessionFactoryImpl.java:409)
at org.hibernate.proxy.AbstractLazyInitializer.checkTargetState(AbstractLazyInitializer.java:108)
at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:101)
at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:140)
at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:190)
at it.test.Test_$$_javassist_0.getTestString(Test_$$_javassist_0.java)
at it.test.Test.main(Test.java:108)
Hibernate: select test0_.CODE as CODE0_, test0_.TEST_STRING as TEST2_0_ from TEST test0_
TEST KEY : 1
TEST KEY : 2
====
Do you have any idea?
Attached you'll find some code that replicate the problem.
Thank you in advance,
Massimiliano
Code:
package it.test;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.cfg.Environment;
@Entity(name="TEST")
public class Test
{
private Integer m_iCode = null;
private String m_sTestString = null;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="CODE")
public Integer getCode()
{
return m_iCode;
}
public void setCode(int iCode)
{
m_iCode = iCode;
}
@Column(name="TEST_STRING")
public String getTestString()
{
return m_sTestString;
}
public void setTestString(String s)
{
m_sTestString = s;
}
public static void main(String[] args)
{
String protocol = "jdbc:derby:";
String sUrl = protocol + "/tmp/testDB" + ";create=true";
// Create the SessionFactory from hibernate.cfg.xml
AnnotationConfiguration cfg = new AnnotationConfiguration()
.setProperty("hibernate.dialect", "org.hibernate.dialect.DerbyDialect")
.setProperty("hibernate.connection.url", sUrl)
.setProperty("hibernate.connection.driver_class", "org.apache.derby.jdbc.EmbeddedDriver")
.setProperty("hibernate.order_updates", "true")
.setProperty(Environment.HBM2DDL_AUTO, "create")
.setProperty(Environment.SHOW_SQL, "true");
cfg.addAnnotatedClass(Test.class);
SessionFactory sf = cfg.buildSessionFactory();
Session session = sf.openSession();
// Search for a non-existend object with key 1
try
{
System.err.println (session.load(Test.class, new Integer(1)));
}
catch (Exception e)
{
System.err.println ("ERROR IGNORED");
// Ignore it: I know the object do not exists
}
// Save the object with key 1
try
{
Transaction t = session.beginTransaction();
Test test = new Test();
test.setTestString("TEST STRING FOR KEY WITH VALUE 1");
session.saveOrUpdate(test);
test = new Test();
test.setTestString("TEST STRING FOR KEY WITH VALUE 2");
session.saveOrUpdate(test);
t.commit();
}
catch (Exception e)
{
throw new RuntimeException("This should not happen...", e);
}
// Search for object with key 1 : now it MUST exists...
try
{
Test t = (Test) session.load(Test.class, new Integer(2));
System.out.println ("Test with key 2 : " + t.getTestString());
t = (Test) session.load(Test.class, new Integer(1));
System.out.println ("Test with key 1 : " + t.getTestString());
}
catch (Exception e)
{
// Ignore it: I know the object do not exists
System.out.println ("WHY???");
e.printStackTrace();
Query query = session.createQuery("from " + Test.class.getName());
for (Object obj : query.list())
{
Test t = (Test) obj;
System.out.println ("TEST KEY : " + t.getCode());
}
}
}
}