зимняя спячка и весенняя устойчивость. Возможное значение идентичности не увеличено? - PullRequest
2 голосов
/ 13 октября 2009

Я использую Hibernate 3.2.6 и Spring 2.5.6 База данных, к которой я подключаюсь: DB2 for Z OS 390 V8.1

Когда я запускаю свой тестовый пример (ниже), я сохраняю объект файла теста. Hibernate ДЕЛАЕТ Сохранить объект в базе данных, но мой тест вылетает после сохранения, где он пытается обновить объект с правильным идентификатором. Я думаю, что он не получает правильный идентификатор (похоже, он получает '0' для идентификатора), или я даже не уверен, почему он пытается обновить объект, который уже существует. Я не знаю, это проблема весны, спячки, картографии, диалекта и т. Д.

Моя конфигурация:

Бизнес-объект:

<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>

Пойо:

/*
 * 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;
    }
}

Контекст приложения:

<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);
    }

}

Мой тест:

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);
    }

Вывод на консоль из 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=?

Трассировка:

org.springframework.dao.DataIntegrityViolationException: не удалось обновить: [Cat.edis.tmiweb.business.File # 0]; вложенное исключение org.hibernate.exception.DataException: не удалось обновить: [cat.edis.tmiweb.business.File # 0] в org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException (SessionFactoryUtils.java:639) в org.springframework.orm.hibernate3.HibernateAccessor.convertHibernateAccessException (HibernateAccessor.java:412) в org.springframework.orm.hibernate3.HibernateTemplate.doExecute (HibernateTemplate.java:424) в org.springframework.orm.hibernate3.HibernateTemplate.executeWithNativeSession (HibernateTemplate.java:374) в org.springframework.orm.hibernate3.HibernateTemplate.save (HibernateTemplate.java:694) в cat.edis.tmiweb.dao.FileDAOImpl.save (FileDAOImpl.java:31) в cat.edis.tmiweb.dao.FileDAOImplTest.testSaveBlob (FileDAOImplTest.java:50) в sun.reflect.NativeMethodAccessorImpl.invoke0 (Native Метод) в sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:85) в sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:58) в sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:60) в java.lang.reflect.Method.invoke (Method.java:391) в junit.framework.TestCase.runTest (TestCase.java:154) в org.jmock.core.VerifyingTestCase.runBare (VerifyingTestCase.java:39) в junit.framework.TestResult $ 1.Protect (TestResult.java:106) в junit.framework.TestResult.runProtected (TestResult.java:124) в junit.framework.TestResult.run (TestResult.java:109) в junit.framework.TestCase.run (TestCase.java:118) в junit.framework.TestSuite.runTest (TestSuite.java:208) в junit.framework.TestSuite.run (TestSuite.java:203) в org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests (RemoteTestRunner.java:436) в org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run (RemoteTestRunner.java:311) в org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main (RemoteTestRunner.java:192) Вызванный: org.hibernate.exception.DataException: не удалось обновить: [cat.edis.tmiweb.business.File # 0] в org.hibernate.exception.SQLStateConverter.convert (SQLStateConverter.java:77) в org.hibernate.exception.JDBCExceptionHelper.convert (JDBCExceptionHelper.java:43) в org.hibernate.persister.entity.AbstractEntityPersister.update (AbstractEntityPersister.java:2430) в org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert (AbstractEntityPersister.java:2312) в org.hibernate.persister.entity.AbstractEntityPersister.update (AbstractEntityPersister.java:2612) в org.hibernate.action.EntityUpdateAction.execute (EntityUpdateAction.java:96) в org.hibernate.engine.ActionQueue.execute (ActionQueue.java:279) в org.hibernate.engine.ActionQueue.executeActions (ActionQueue.java:263) в org.hibernate.engine.ActionQueue.executeActions (ActionQueue.java:168) вorg.hibernate.event.def.AbstractFlushingEventListener.performExecutions (AbstractFlushingEventListener.java:298) в org.hibernate.event.def.DefaultFlushEventListener.onFlush (DefaultFlushEventListener.java:27) в org.hibernate.impl.SessionImpl.flush (SessionImpl.java:1000) в org.springframework.orm.hibernate3.HibernateAccessor.flushIfNecessary (HibernateAccessor.java:390) в org.springframework.orm.hibernate3.HibernateTemplate.doExecute (HibernateTemplate.java:420) ... еще 20 причин: COM.ibm.db2.jdbc.DB2Exception: [IBM] [Драйвер CLI] [DB2] SQL0100W Нет была найдена строка для FETCH, UPDATE или УДАЛЯТЬ; или результат запроса является пустая таблица SQLSTATE = 02000

в COM.ibm.db2.jdbc.app.SQLExceptionGenerator.throw_SQLException (Неизвестно Источник) в COM.ibm.db2.jdbc.app.SQLExceptionGenerator.throw_SQLException (Неизвестно Источник) в COM.ibm.db2.jdbc.app.SQLExceptionGenerator.check_return_code (Неизвестно Источник) в COM.ibm.db2.jdbc.app.DB2PreparedStatement.loadParameters (Неизвестно Источник) в COM.ibm.db2.jdbc.app.DB2PreparedStatement.execute2 (Неизвестно Источник) в COM.ibm.db2.jdbc.app.DB2PreparedStatement.executeUpdate (Неизвестно Источник) в cat.cis.tuf.server.connector.jdbc.v1.JDBCv1DBStatement.executeUpdate (JDBCv1DBStatement.java:206) в org.hibernate.jdbc.NonBatchingBatcher.addToBatch (NonBatchingBatcher.java:23) в org.hibernate.persister.entity.AbstractEntityPersister.update (AbstractEntityPersister.java:2408) ... еще 31

Объект исключения:

 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

**

Переключено на драйвер типа 4: (все еще используется org.hibernate.dialect.DB2390Dialect)

НОВАЯ ошибка! ** \

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

Ответы [ 4 ]

0 голосов
/ 26 марта 2012
  • Вы взяли содержимое в качестве байта [] в File.java, но вы не определили его файл отображения hbm. Чтобы определить его отображение, вам нужно указать свойство ниже, иначе вы должны удалить из File.java

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

  • Вы указали contentBlob как большой двоичный объект в файле hbm, но вы не указали в File.java. Итак, вы должны добавить его установщик-получатель сопоставления в связанный с ним POJO (File.java) или удалить из файла hbm.
0 голосов
/ 14 октября 2009

Из журналов похоже, что hibernate вставляет объект, затем пытается обновить его, но не может найти только что вставленный объект. Я не уверен, но это может быть проблема с настроенным генератором идентификатора. Включите ведение журнала для уровня org.hibernate.type и проверьте, какие значения связаны с подготовленным оператором - это даст вам лучшее представление о том, как это отладить.

0 голосов
/ 14 октября 2009

не решено. До сих пор не удалось выяснить, почему возвращаемый идентификатор равен «0», поэтому, когда Hibernate запускает обновление sql, строки с идентификатором «0» нет. Но даже лучше, чем почему, решение для правильной работы будет лучше.

0 голосов
/ 14 октября 2009

Удалить / закомментировать

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

И снова запустите тест с нуля

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...