Hibernate and spring. Possible ID value not increasing?

I am using hibernate 3.2.6 and spring 2.5.6 Im Connecting Database: DB2 for Z OS 390 V8.1

When I run my test file (below), I save the test file object. Hibernate DOES Save the object to the database, but my test gets deleted after saving when it tries to update the object with the correct id. I think it is not getting the correct id (it looks like it is getting "0" for id), or Im not even sure why it is trying to update an object that is already being saved. I don't know if this is a spring issue, hibernation, collation, dialect, etc.

My config:

Business object:

<hibernate-mapping>

    <class name="cat.edis.tmiweb.business.File" table="FILE">

        <id name="id" type="java.lang.Long" column="gen_file_id">
            <generator class="native"></generator>
        </id>

        <property name="creationTimeStamp" type="java.util.Date" column="crte_ts" />
        <property name="name" type="java.lang.String" column="file_nm" />
        <property name="type" type="java.lang.String" column="file_typ_desc" />
        <property name="description" type="java.lang.String" column="file_desc" />
        <property name="length" type="java.lang.Long" column="file_lgth" />
        <property name="contentBlob" type="blob" column="file_cntnt" />

    </class>

</hibernate-mapping>

      

Poho:

/*
 * Created on Oct 9, 2009
 *
 */
package cat.edis.tmiweb.business;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Blob;
import java.sql.SQLException;
import java.util.Date;

import org.hibernate.Hibernate;

/**
 * @author dudekta
 */
public class File {
    private Long id;
    private Date creationTimeStamp;
    private String name;
    private String type;
    private String description;
    private Long length;
    private byte[] content;


    /** Don't invoke this. Used by Hibernate only. */
    public void setContentBlob(Blob imageBlob) {
     this.content = this.toByteArray(imageBlob);
    }

    /** Don't invoke this. Used by Hibernate only. */
    public Blob getContentBlob() {
     return Hibernate.createBlob(this.content);
    }

    private byte[] toByteArray(Blob fromBlob) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try {
         return toByteArrayImpl(fromBlob, baos);
        } catch (SQLException e) {
         throw new RuntimeException(e);
        } catch (IOException e) {
         throw new RuntimeException(e);
        } finally {
         if (baos != null) {
          try {
           baos.close();
          } catch (IOException ex) {
          }
         }
        }
       }

    private byte[] toByteArrayImpl(Blob fromBlob, ByteArrayOutputStream baos)
    throws SQLException, IOException {
    byte[] buf = new byte[4000];
    InputStream is = fromBlob.getBinaryStream();
    try {
     for (;;) {
      int dataSize = is.read(buf);

      if (dataSize == -1)
       break;
      baos.write(buf, 0, dataSize);
     }
    } finally {
     if (is != null) {
      try {
       is.close();
      } catch (IOException ex) {
      }
     }
    }
    return baos.toByteArray();
   }

    /**
     * @return Returns the creationTimeStamp.
     */
    public Date getCreationTimeStamp() {
        return creationTimeStamp;
    }
    /**
     * @param creationTimeStamp
     *            The creationTimeStamp to set.
     */
    public void setCreationTimeStamp(Date creationTimeStamp) {
        this.creationTimeStamp = creationTimeStamp;
    }
    /**
     * @return Returns the description.
     */
    public String getDescription() {
        return description;
    }
    /**
     * @param description
     *            The description to set.
     */
    public void setDescription(String description) {
        this.description = description;
    }
    /**
     * @return Returns the id.
     */
    public Long getId() {
        return id;
    }
    /**
     * @param id
     *            The id to set.
     */
    public void setId(Long id) {
        this.id = id;
    }
    /**
     * @return Returns the length.
     */
    public Long getLength() {
        return length;
    }
    /**
     * @param length
     *            The length to set.
     */
    public void setLength(Long length) {
        this.length = length;
    }
    /**
     * @return Returns the name.
     */
    public String getName() {
        return name;
    }
    /**
     * @param name
     *            The name to set.
     */
    public void setName(String name) {
        this.name = name;
    }
    /**
     * @return Returns the type.
     */
    public String getType() {
        return type;
    }
    /**
     * @param type
     *            The type to set.
     */
    public void setType(String type) {
        this.type = type;
    }
    /**
     * @return Returns the content.
     */
    public byte[] getContent() {
        return content;
    }

    /**
     * @param content
     *            The content to set.
     */
    public void setContent(byte[] content) {
        this.content = content;
    }
}

      

Application context:

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

    <!--  Webservices -->
    <bean id="FPSService" class="cat.edis.tmiweb.services.fps.FPSServiceImpl">
        <constructor-arg type="java.lang.String" value="http://localhost:8888/someendpoint" />
        <constructor-arg type="java.lang.String" value="bill" />
        <constructor-arg type="java.lang.String" value="will" />
    </bean>

    <!--  Database stuff that we should separate out-->

    <bean id="fileDAO" class="cat.edis.tmiweb.dao.FileDAOImpl">
        <property name="sessionFactory">
            <ref bean="TMISessionFactory" />
        </property>
    </bean>

    <bean id="TMIDataSource" class="cat.cis.template.spring.util.TUFDataSource" destroy-method="close">
        <property name="poolName" value="db2OS390GenData" />
    </bean>

    <bean id="TMISessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="dataSource" ref="TMIDataSource" />

        <property name="mappingResources">
            <list>
                <!-- PUT HIBERNATE MAPPING FILES HERE -->
                <value>cat/edis/tmiweb/business/File.hbm.xml</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <map>
                <entry>
                    <key>
                        <value>hibernate.show_sql</value>
                    </key>
                    <value>true</value>
                </entry>
                <entry>
                    <key>
                        <value>hibernate.default_schema</value>
                    </key>
                    <value>N4GK001$</value>
                </entry>
                <entry>
                    <key>
                        <value>hibernate.dialect</value>
                    </key>
                    <ref bean="TMIDialect" />
                </entry>
            </map>
        </property>
    </bean>

    <bean id="TMIDialect" factory-bean="TMIDialectFactory" factory-method="instance" />

    <bean id="TMIDialectFactory" class="cat.cis.template.spring.util.EnvironmentBeanStrategyFactory">
        <property name="envKey" value="tuf.environment" />
        <property name="defaultKey" value="DEV" />
        <property name="target">
            <map>
                <entry key="DEV" value="org.hibernate.dialect.DB2390Dialect" />
                <entry key="TEST" value="org.hibernate.dialect.DB2390Dialect" />
                <entry key="QA" value="org.hibernate.dialect.DB2390Dialect" />
                <entry key="PROD" value="org.hibernate.dialect.DB2390Dialect" />
            </map>
        </property>
    </bean>

    <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory">
            <ref bean="TMISessionFactory" />
        </property>
    </bean>

</beans>

      

FileDAO:

/*
 * Created on Oct 9, 2009
 */
package cat.edis.tmiweb.dao;

import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import cat.edis.tmiweb.business.File;

/**
 * @author dudekta
 *  
 */
public class FileDAOImpl extends HibernateDaoSupport implements FileDAO {

    /**
     * 
     * @param id
     * @return
     */
    public File load(Long id) {
        return (File) getHibernateTemplate().get(File.class, id);
    }

    /**
     * 
     * @param file
     * @return
     */
    public void save(File file) {
        getHibernateTemplate().save(file);
    }

}

      

My test:

public void testSaveBlob() {
        FileDAO fileDAO =(FileDAO)SpringTestInitializer.getContext().getBean("fileDAO");
        File file = new File();
        file.setName("TestMe");
        file.setType("txt");
        file.setCreationTimeStamp(new Date());
        file.setDescription("idc");

        byte[] testBytes = new byte[1024];
        byte byteValue = 1;
        for (int i = 0; i < testBytes.length; i++) {
            testBytes[i] = byteValue;
        }
        file.setLength(new Long(testBytes.length));
        file.setContent(testBytes);
        fileDAO.save(file);

        File dbFile = fileDAO.load(file.getId());
        assertNotNull(file);
    }

      

Console output from Hibernate:

Initializing Spring....
Spring test context created....
Hibernate: insert into N4GK001$.FILE (gen_file_id, crte_ts, file_nm, file_typ_desc, file_desc, file_lgth, file_cntnt) values (default, ?, ?, ?, ?, ?, ?)
Hibernate: select identity_val_local() from sysibm.sysdummy1
Hibernate: update N4GK001$.FILE set crte_ts=?, file_nm=?, file_typ_desc=?, file_desc=?, file_lgth=?, file_cntnt=? where gen_file_id=?

      

Trace:

org.springframework.dao.DataIntegrityViolationException: Failed to update: [Cat.edis.tmiweb.business.File # 0]; nested exception org.hibernate.exception.DataException: Failed to update: [cat.edis.tmiweb.business.File # 0] in org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException (SessionFactoryUtils.java:639) in org.springframe .orm.hibernate3.HibernateAccessor.convertHibernateAccessException (HibernateAccessor.java:412) in org.springframework.orm.hibernate3.HibernateTemplate.doExecute (HibernateTemplate.java:424) in org.springframework.orm.hava:424) in org.springframework.ormtehava:424 : 374) at org.springframework.orm.hibernate3.HibernateTemplate.save (HibernateTemplate.java:694) at cat.edis.tmiweb.dao.FileDAOImpl.save (FileDAOImpl.java:31) at cat.edis.tmiweb.dao.FileDAOImplTest.testSaveBlob (FileDAOImplTest.java:50) at sun.reflect.NativeMethodAccessorImpl.invoke0 (Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.javaflect.invoke (NativeMethodAccessorImpl.java:85) at sun.reflect.AccessorImpl.javaflect. 58) at sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:60) at java.lang.reflect.Method.invoke (Method.java:391) at junit.framework.TestCase.runTest (TestCase.java:154) at org.jmock.core.VerifyingTestCase.runBare (VerifyingTestCase.java:39) in junit.framework.TestResult $ 1.Protect (TestResult.java:106) in junit.framework.TestResult.runProtected (TestResult.java:124) in junit.framework.TestResult.runProtected (TestResult.java:124) framework.TestResult.run (TestResult.java:109) at junit.framework.TestCase.run (TestCase.java:118) at junit.framework.TestSuite.runTest (TestSuite.java:208) at junit.framework.TestSuite.run (TestSuite.java:203) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests (RemoteTestRunner.java:436) at org.eclipse.jdt.internal.junit.runestRunner.Remote. run (RemoteTestRunner.java:311) in org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main (RemoteTestRunner.java:192) Called: org.hibernate.exception.DataException: Failed to update: [cat.edis. tmiweb.business.File # 0] at org.hibernate.exception.SQLStateConverter.convert (SQLStateConverter.java:77) at org.hibernate.exception.JDBCExceptionHelper.convert (JDBCExceptionHelper.java:43) at org.hibernate.persister. .AbstractEntityPersister.update (AbstractEntityPersister.java:2430) at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert (AbstractEntityPersister.java:2312) at org.hibernate.persister.entity.AbstractEntityPersisterupdate (AbstractEntityPersister.java:2612) at org.hibernate.action.EntityUpdateAction.execute (EntityUpdateAction.java:96) at org.hibernate.engine.ActionQueue.execute (ActionQueue.java:279) at org.hibernateQueue.Action .executeActions (ActionQueue.java:263) in org.hibernate.engine.ActionQueue.executeActions (ActionQueue.java:168) in org.hibernate.event.def.AbstractFlushingEventListener.performExecutions (AbstractFlibernateEventListener.java:298) event.def.DefaultFlushEventListener.onFlush (DefaultFlushEventListener.java:27) at org.hibernate.impl.SessionImpl.flush (SessionImpl.java:1000) at org.springframework.orm.hibernate3.Hibernate.jpexorccess.flushIfNecessary90ccess at org.springframework.orm.hibernate3.HibernateTemplate.doExecute (HibernateTemplate.java:420) ... 20 more Reasons: COM.ibm.db2.jdbc.DB2Exception: [IBM] [CLI Driver] [DB2] SQL0100W No row found for FETCH, UPDATE, or DELETE; or the query results in an empty table. SQLSTATE = 02000

at COM.ibm.db2.jdbc.app.SQLExceptionGenerator.throw_SQLException (Unknown Source) at COM.ibm.db2.jdbc.app.SQLExceptionGenerator.throw_SQLException (Unknown Source) at COM.ibm.db2.jdbc.app.SQLEcoderet_ceptionGeneck (Source Unknown) at COM.ibm.db2.jdbc.app.DB2PreparedStatement.loadParameters (Source Unknown) at COM.ibm.db2.jdbc.app.DB2PreparedStatement.execute2 (Source Unknown) at COM.ibm.db2.jdbc.app .DB2PreparedStatement.executeUpdate (Unknown Source) at cat.cis.tuf.server.connector.jdbc.v1.JDBCv1DBStatement.executeUpdate (JDBCv1DBStatement.java:206) at org.hibernate.jdbatc.Non.chercher at org.hibernate.persister.entity.AbstractEntityPersister.update (AbstractEntityPersister.java:2408) ... 31 more

Exception object:

 ex= DataException  (id=341)
backtrace= Object[35]  (id=349)
cause (NestableRuntimeException)= DB2Exception  (id=325)
cause (Throwable)= DataException  (id=341)
delegate= NestableDelegate  (id=350)
detailMessage= "could not update: [cat.edis.tmiweb.business.File#0]"
sql= "update N4GK001$.FILE set crte_ts=?, file_nm=?, file_typ_desc=?, file_desc=?, file_lgth=?, file_cntnt=? where gen_file_id=?"
sqle= DB2Exception  (id=325)
stackTrace= null

      

**

Switched to driver type 4: (still used by org.hibernate.dialect.DB2390Dialect)

NEW error! ** \

org.springframework.orm.hibernate3.HibernateOptimisticLockingFailureException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1; nested exception is org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
   at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:672)
   at org.springframework.orm.hibernate3.HibernateAccessor.convertHibernateAccessException(HibernateAccessor.java:412)
   at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:424)
   at org.springframework.orm.hibernate3.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:374)
   at org.springframework.orm.hibernate3.HibernateTemplate.save(HibernateTemplate.java:694)
   at cat.edis.tmiweb.dao.FileDAOImpl.save(FileDAOImpl.java:31)
   at cat.edis.tmiweb.dao.FileDAOImplTest.testSaveBlob(FileDAOImplTest.java:50)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:85)
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:58)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:60)
   at java.lang.reflect.Method.invoke(Method.java:391)
   at junit.framework.TestCase.runTest(TestCase.java:154)
   at org.jmock.core.VerifyingTestCase.runBare(VerifyingTestCase.java:39)
   at junit.framework.TestResult$1.protect(TestResult.java:106)
   at junit.framework.TestResult.runProtected(TestResult.java:124)
   at junit.framework.TestResult.run(TestResult.java:109)
   at junit.framework.TestCase.run(TestCase.java:118)
   at junit.framework.TestSuite.runTest(TestSuite.java:208)
   at junit.framework.TestSuite.run(TestSuite.java:203)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:436)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:311)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
   at org.hibernate.jdbc.Expectations$BasicExpectation.checkBatched(Expectations.java:61)
   at org.hibernate.jdbc.Expectations$BasicExpectation.verifyOutcome(Expectations.java:46)
   at org.hibernate.jdbc.NonBatchingBatcher.addToBatch(NonBatchingBatcher.java:24)
   at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2408)
   at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:2312)
   at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2612)
   at org.hibernate.action.EntityUpdateAction.execute(EntityUpdateAction.java:96)
   at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:279)
   at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:263)
   at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:168)
   at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
   at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
   at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
   at org.springframework.orm.hibernate3.HibernateAccessor.flushIfNecessary(HibernateAccessor.java:390)
   at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:420)
   ... 20 more

      

+2


source to share


4 answers


Delete / comment

 
        File dbFile = fileDAO.load (file.getId ());
        assertNotNull (file);


And run the test again from scratch

0


source


From the logs, it looks like hibernate is inserting an object, then trying to update it, but it cannot find the object it just inserted. I'm not sure, but this could be a problem when setting up an id generator. Enable logging for the org.hibernate.type level and check that the values ​​are bound to the pre-prepared statement. - this will give you a better idea of ​​how to debug this



0


source


This has not been resolved. Still not nailed down why the returned id is "0", so when Hibernate runs the sql update, there is no row with id "0". But even better than why, a solution to get it to work correctly would be better.

0


source


  • You loaded the content as byte [] in File.java, but you haven't defined its display hbm file. To define its mapping you need to put below else property which you should remove from File.java

<property name="image" type="binary"> <column name="IMAGE" not-null="true" /> </property>

  • You specified contentBlob as a blob in your hbm file, but you did not specify it in File.java. So you have to add it setter-getter to match in its associated POJO (File.java) or remove from hbm file.
0


source







All Articles