Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

org.hibernate.ObjectNotFoundException: No row with the given identifier exists, but it DOES

I've got a hibernate problem that I can't fix.

The setup: Java EE, web app, Hibernate 3.2, Tomcat 6, Struts 2.

Basically, I persist an object with my server logic (a struts action), then try and pull that data out for the next page and display it.

I check the database after I save the object, and sure enough, I can see the row there with all the data.

But when I try and retrieve it I get this:

org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [msc.model.Picture#73]

To make things even muddier, when I restart Tomcat and try and access the same object, I don't get the error - Hibernate finds the row just fine.

Hibernate will also be able to see the row if I do some other operations - maybe add a row here and there to the database, not even on the same table.

From all this I suspect a Hibernate bug, but I'm a Hibernate newbie so I am probably wrong. Please help! I've googled and googled to no avail.

Here is my Hibernate config:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/msc</property>
        <property name="hibernate.connection.username">root</property>
        <property name="hibernate.connection.password">-------</property>
        <!-- JDBC connection pool (use the built-in) -->
        <property name="connection.pool_size">80</property>
        <property name="current_session_context_class">thread</property>
        <!-- Echo all executed SQL to stdout -->
        <property name="show_sql">true</property>
        <mapping resource="msc/model/Picture.hbm.xml"/>
        <mapping resource="msc/model/Comment.hbm.xml"/>
    </session-factory>
</hibernate-configuration>

Here are my two mapping files:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
  <class name="msc.model.Picture" table="PICTURE">
    <id column="PICTURE_ID" name="id">
      <generator class="native"/>
    </id>
    <property name="story"/>
    <property name="email"/>
    <property name="category"/>
    <property name="state"/>
    <property name="ratings"/>
    <property name="views"/>
    <property name="timestamp"/>
    <property name="title"/>
    <property lazy="true" name="image" type="blob">
      <column name="IMAGE"/>
    </property>
    <property lazy="true" name="refinedImage" type="blob">
      <column name="REFINEDIMAGE"/>
    </property>
    <property lazy="true" name="thumbnail" type="blob">
      <column name="THUMBNAIL"/>
    </property>
    <bag cascade="save-update" lazy="true" name="comments" table="COMMENT">
      <key column="PICTURE"/>
      <one-to-many class="msc.model.Comment"/>
    </bag>
  </class>
</hibernate-mapping>

and

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
  <class name="msc.model.User" table="USER">
    <id column="USER_ID" name="id">
      <generator class="native"/>
    </id>
    <property name="username"/>
    <property name="email"/>
    <bag cascade="save-update" lazy="true" name="pictures" table="PICTURE">
      <key column="USER"/>
      <one-to-many class="msc.model.Picture"/>
    </bag>
    <bag cascade="save-update" lazy="true" name="comments" table="COMMENT">
      <key column="USER"/>
      <one-to-many class="msc.model.Comment"/>
    </bag>
  </class>
</hibernate-mapping>

Please let me know if you need more info, I'm happy to oblige.

(note: this is not a duplicate of this question, the scenario is not the same "No row with the given identifier exists" although it DOES exist)

EDIT: as requested, posting Java code:

Code to save object

Session hib_ses = HibernateUtil.getSessionFactory().getCurrentSession();

hib_ses.beginTransaction();

hib_ses.save(user);

hib_ses.getTransaction().commit(); 

Code to display data (an image in this case)

public class ImageAction extends ActionSupport implements ServletResponseAware, SessionAware {

    private HttpServletResponse response;
    Map session;
    private Long id;
    private int thumbnail;
    private InputStream inputStream;

    @Override
    public String execute() throws Exception {
        response.setContentType("image/jpeg");
        Session hib_session = HibernateUtil.getSessionFactory().getCurrentSession();
        hib_session.beginTransaction();

        //what is the ID now?
        Picture pic = (Picture) hib_session.load(Picture.class, getId());

        if (thumbnail == 1) {
            inputStream = (ByteArrayInputStream) pic.getThumbnail().getBinaryStream();
        } else {
            inputStream = (ByteArrayInputStream) pic.getRefinedImage().getBinaryStream();
        }

        hib_session.close();
        return SUCCESS;
    }
like image 291
nasty pasty Avatar asked Jan 24 '12 09:01

nasty pasty


People also ask

Which is true for get () method when no row with the given identifier value exists in the database?

Get() method return null, If no row is available in the session cache or the database for the given identifier whereas load() method throws object not found exception.


3 Answers

This happens because you have inserted something which is meant to be a foreign key but do not reference anything. Check out you database whether that key exist or not(even though it is in database in other tables).

like image 185
Amit Kumar Avatar answered Sep 21 '22 02:09

Amit Kumar


Check all your mappings and database settings. It may be possible you are setting some not-null="true" in foreign key relations when your database says nullable="true". The first causes an INNER JOIN and the second causes LEFT JOIN.

Set log level to TRACE to see all steps and look for generated SQL when retrieving the objects.

like image 18
Esteve Camps Avatar answered Sep 22 '22 02:09

Esteve Camps


In many to one relationship you need to tell Hibernate what needs to be done if the mapped row is not found. You can configure it in the following ways:

Annotation:
@NotFound(action = NotFoundAction.IGNORE)
Mapping XML:
<many-to-one name="user" column="user_id" class="com.xyz.User" cascade="save-update, evict" not-found="ignore"/>
like image 10
Rakesh Avatar answered Sep 23 '22 02:09

Rakesh