升级Hibernate 3.6到4.3获取com.microsoft.sqlserver.jdbc.SQLServerException:字符串或二进制数据将被截断

时间:2015-10-29 09:17:36

标签: spring hibernate

我正在将我的遗留应用程序从Hibernate 3.6升级到4.3。该应用程序适用于Hibernate 3.6。但是,在我将应用程序升级到Hibernate 4.3之后,我遇到了com.microsoft.sqlserver.jdbc.SQLServerException:字符串或二进制数据将被截断。

应用程序中这些实体的映射配置未经历任何更改,并且与以前相同。有问题的数据库表都没有改变。所以我现在无法意识到出了什么问题。该应用程序使用的是Spring 4.1和Java 8,MS SQL 2014是数据库。

我搜索了这个错误,人们似乎建议在多对一关系缺少hbm文件的情况下发生这种类型的问题。但是,我没有在下面的配置中看到这一点

<class name="com.mycompany.rm.pmech.common.domain.AdditionalFee"
       table="AdditionalFee">
    <id name="id" column="AdditionalFeeId" type="int">
        <generator class="identity"/>
    </id>
    <many-to-one name="station" column="stationId" class="com.mycompany.rm.pmech.common.domain.Station" />
    <many-to-one name="carGroup" column="carGroupId" class="com.mycompany.rm.pmech.common.domain.CarGroup" />
    <property name="effectiveDate" column="EffectiveDate" />
    <property name="feeType" column="FeeType" type="com.mycompany.rm.pmech.common.hibernate.types.HibernateFeeType"/>
    <property name="feeAmount" column="FeeAmount" type="com.mycompany.rm.common.types.DecimalUserType" />
    <property name="feeCalculationType" column="FeeUnit" type="com.mycompany.rm.pmech.common.hibernate.types.HibernateFeeCalculationType" />
    <property name="taxable" column="taxable" type="boolean" />
</class>

以下是我的表格外观

CREATE TABLE [[AdditionalFee](
            [AdditionalFeeId] [bigint] IDENTITY(1,1) NOT NULL,
            [CarGroupId] [int] NOT NULL,
            [StationId] [int] NOT NULL,
            [EffectiveDate] [datetime] NOT NULL,
            [FeeType] [varchar](3) NOT NULL,
            [FeeUnit] [varchar](1) NOT NULL,
            [FeeAmount] [money] NOT NULL,
            [Taxable] [bit] NOT NULL,
)

这是之前使用的配置和表,并且与hibernate 3.6一起工作正常,所以我并不怀疑它是关系映射的问题。

以下是保存实体时抛出异常的代码。

getHibernateTemplate().save(additionalFee);

以下是异常的堆栈跟踪。

org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; nested exception is org.hibernate.exception.DataException: could not execute statement
            at org.springframework.orm.hibernate4.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:167)
            at org.springframework.orm.hibernate4.HibernateTemplate.doExecute(HibernateTemplate.java:343)
            at org.springframework.orm.hibernate4.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:308)
            at org.springframework.orm.hibernate4.HibernateTemplate.save(HibernateTemplate.java:617)
            at com.mycompany.rm.pmech.common.dao.GenericDAO.save(GenericDAO.java:378)
            at com.mycompany.rm.pmech.common.domain.AdditionalChargesCalculatorTest.setupStation(AdditionalChargesCalculatorTest.java:1705)
            at com.mycompany.rm.pmech.common.domain.AdditionalChargesCalculatorTest.onSetUp(AdditionalChargesCalculatorTest.java:1569)
            at org.springframework.test.AbstractSingleSpringContextTests.setUp(AbstractSingleSpringContextTests.java:104)
            at org.springframework.test.ConditionalTestCase.runBare(ConditionalTestCase.java:79)
            at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:84)
            at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
            at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78)
            at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212)
            at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68)
            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
            at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
            at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
Caused by: org.hibernate.exception.DataException: could not execute statement
            at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:135)
            at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:49)
            at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:126)
            at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:112)
            at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:211)
            at org.hibernate.id.IdentityGenerator$GetGeneratedKeysDelegate.executeAndExtract(IdentityGenerator.java:96)
            at org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:58)
            at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3032)
            at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3558)
            at org.hibernate.action.internal.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:98)
            at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:492)
            at org.hibernate.engine.spi.ActionQueue.addResolvedEntityInsertAction(ActionQueue.java:197)
            at org.hibernate.engine.spi.ActionQueue.addInsertAction(ActionQueue.java:181)
            at org.hibernate.engine.spi.ActionQueue.addAction(ActionQueue.java:216)
            at org.hibernate.event.internal.AbstractSaveEventListener.addInsertAction(AbstractSaveEventListener.java:324)
            at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:288)
            at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:194)
            at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:125)
            at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:209)
            at org.hibernate.event.internal.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:55)
            at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:194)
            at org.hibernate.event.internal.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:49)
            at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:90)
            at org.hibernate.internal.SessionImpl.fireSave(SessionImpl.java:715)
            at org.hibernate.internal.SessionImpl.save(SessionImpl.java:707)
            at org.hibernate.internal.SessionImpl.save(SessionImpl.java:702)
            at org.springframework.orm.hibernate4.HibernateTemplate$12.doInHibernate(HibernateTemplate.java:621)
            at org.springframework.orm.hibernate4.HibernateTemplate$12.doInHibernate(HibernateTemplate.java:617)
            at org.springframework.orm.hibernate4.HibernateTemplate.doExecute(HibernateTemplate.java:340)
            ... 24 more
Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: String or binary data would be truncated.
            at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:197)
            at com.microsoft.sqlserver.jdbc.SQLServerStatement.getNextResult(SQLServerStatement.java:1493)
            at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.doExecutePreparedStatement(SQLServerPreparedStatement.java:390)
            at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement$PrepStmtExecCmd.doExecute(SQLServerPreparedStatement.java:340)
           at com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:4575)
            at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:1400)
            at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeCommand(SQLServerStatement.java:179)
            at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeStatement(SQLServerStatement.java:154)
            at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.executeUpdate(SQLServerPreparedStatement.java:308)
            at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:208)
            ... 48 more

非常感谢任何有助于解决问题的帮助/指示。

1 个答案:

答案 0 :(得分:0)

我有类似的问题,终于设法解决了它: 在hibernate3下,我为我的enumType(Sex)制作了一个特殊的enumType。迁移到hibernate4时似乎不再需要了,所以我删除了它。一切都运行正常,但在一个非常特殊的情况下,我从sql server收到消息,数据将被截断。

使用SQL事件探查器(可能与您的SQL服务器一起安装),我设法看到实际发送到数据库的内容,并看到我的枚举类型的值太长。然后我从

更改了我的hibernate映射
    <property name="sex" column="SEX"/>

    <property name="sex" column="SEX">
        <type name="org.hibernate.type.EnumType">
            <param name="enumClass">ch.in4medicine.e4med.common.Sex</param>
        </type>
    </property>

一切都有效(目前)。

我身边有两个提示:

  • 使用SQL事件探查器查看实际发送给DB的内容
  • 检查您是否正确映射了枚举。