当前位置: 首页 > 面试题库 >

使用层叠=“保存更新”保存时的休眠异常

凤扬
2023-03-14
问题内容

这分别是我的hbm和测试代码。我正在使用Spring的HibernateTemplate。我不使用DAO。使用Spring 2.0.7的Hibernate
2.2.5

血红蛋白

<class name="Product" table="PRODUCT">
        <id name="id" type="java.lang.Long" column="ID">
            <generator class="native">
                <param name="sequence">PRODUCT_SN</param>
            </generator>
        </id>

        <set name="children" lazy="false" table="PRODUCT" cascade="save-update">
            <key>
                <column name="ID" />
            </key>
            <one-to-many class="Product" />
        </set>
        <property name="code" type="java.lang.String" column="CODE" not-null="true" />
        <property name="name" type="java.lang.String" column="NAME" />
        <property name="startDate" type="java.util.Date" column="STARTDATE" />
        <property name="endDate" type="java.util.Date" column="ENDDATE" />
        <property name="decisionable" type="boolean" column="ISDECISIONABLE" />
        <property name="selectable" type="boolean" column="ISSELECTABLE" />
    </class>

测试

public class ProductTest extends HibernateTestCase
{
    @Test
    public void save()
    {
        // Level 1 - mortgage LOB
        Product mortgage = new Product();
        mortgage.setCode("Mortgage");

        Product ml = new Product();
        ml.setCode("Mortgage Loan");

        Product me = new Product();
        me.setCode("Home Equity LOC");

        mortgage.addChild(ml);
        // mortgage.addChild(me);

        hibernateTemplate.save(mortgage);
    }

    @Override
    public List<String> getHbmResourceUnderTest()
    {
        return Lists.newArrayList("Product.hbm.xml");
    }
}

超级测试班

public abstract class HibernateTestCase
{
    protected HibernateTemplate hibernateTemplate;

    protected TransactionTemplate transTemplate;

    public TransactionTemplate getTransTemplate()
    {
        return transTemplate;
    }

    protected PlatformTransactionManager transactionManager;

    @Before
    public void setUp() throws Exception
    {
        Configuration configuration = new Configuration();
        configuration.setProperty(Environment.DRIVER, "org.hsqldb.jdbcDriver");
        configuration.setProperty(Environment.URL, "jdbc:hsqldb:mem:test");
        configuration.setProperty(Environment.USER, "sa");
        configuration.setProperty(Environment.DIALECT, HSQLDialect.class.getName());
        configuration.setProperty(Environment.SHOW_SQL, "true");
        configuration.setProperty(Environment.HBM2DDL_AUTO, "create-drop");
        configuration.setProperty(Environment.STATEMENT_BATCH_SIZE, "5");

        for (String resource : getHbmResourceUnderTest())
        {
            configuration.addResource(resource);
        }
        SessionFactory sessionFactory = configuration.buildSessionFactory();

        transactionManager = new HibernateTransactionManager(sessionFactory);
        hibernateTemplate = new HibernateTemplate(sessionFactory);
        transTemplate = new TransactionTemplate(transactionManager);
    }

    public abstract List<String> getHbmResourceUnderTest();
}

错误

insert into PRODUCT (ID, CODE, NAME, STARTDATE, ENDDATE, ISDECISIONABLE, ISSELECTABLE) values (null, ?, ?, ?, ?, ?, ?)
binding 'Mortgage' to parameter: 1
binding null to parameter: 2
binding null to parameter: 3
binding null to parameter: 4
binding 'false' to parameter: 5
binding 'false' to parameter: 6
Hibernate: call identity()
insert into PRODUCT (ID, CODE, NAME, STARTDATE, ENDDATE, ISDECISIONABLE, ISSELECTABLE) values (null, ?, ?, ?, ?, ?, ?)
binding 'Mortgage Loan' to parameter: 1
binding null to parameter: 2
binding null to parameter: 3
binding null to parameter: 4
binding 'false' to parameter: 5
binding 'false' to parameter: 6
Hibernate: call identity()
update PRODUCT set ID=? where ID=?
binding '1' to parameter: 1
binding '2' to parameter: 2
SQL Error: 0, SQLState: null

ERROR [org.hibernate.util.JDBCExceptionReporter] failed batch
ERROR [org.hibernate.event.def.AbstractFlushingEventListener] Could not synchronize database state with session
org.hibernate.exception.GenericJDBCException: Could not execute JDBC batch update
    at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:103)
    at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:91)
    at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
    at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:253)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:237)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:145)
    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.execute(HibernateTemplate.java:373)
    at org.springframework.orm.hibernate3.HibernateTemplate.save(HibernateTemplate.java:632)
    at com.equifax.ic.platform.domain.product.ProductTest.save(ProductTest.java:28)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: java.sql.BatchUpdateException: failed batch
    at org.hsqldb.jdbc.jdbcStatement.executeBatch(Unknown Source)
    at org.hsqldb.jdbc.jdbcPreparedStatement.executeBatch(Unknown Source)
    at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48)
    at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:246)
    ... 32 more

问题答案:

好的,根本原因是我对集合的映射无效。感谢这篇关于复合映射的文章

错误:

<key>
  <column name="ID" />
</key>

正确

<many-to-one name="parent" class="Product" lazy="false" column="PARENT" />

<set name="children" lazy="false" fetch="join" table="PRODUCT" cascade="all">
  <key>
    <column name="PARENT" />
  </key>
  <one-to-many class="Product" />
</set>

完整的映射

<class name="Product" table="PRODUCT">
        <id name="id" type="java.lang.Long" column="ID">
            <generator class="native">
                <param name="sequence">PRODUCT_SN</param>
            </generator>
        </id>

        <many-to-one name="parent" class="Product" lazy="false" column="PARENT" />

        <set name="children" lazy="false" fetch="join" table="PRODUCT" cascade="all">
            <key>
                <column name="PARENT" />
            </key>
            <one-to-many class="Product" />
        </set>
        <property name="code" type="java.lang.String" column="CODE" not-null="true" />
        <property name="name" type="java.lang.String" column="NAME" />
        <property name="startDate" type="java.util.Date" column="STARTDATE" />
        <property name="endDate" type="java.util.Date" column="ENDDATE" />
        <property name="decisionable" type="boolean" column="ISDECISIONABLE" />
        <property name="selectable" type="boolean" column="ISSELECTABLE" />
    </class>


 类似资料:
  • 问题内容: 我正在尝试使用Hibernate插入或更新大数据。我有一个包含350k对象的列表,当我使用Hibernate时,要花费数小时才能插入所有数据。 我正在使用以下代码进行此操作。我的开发环境是JDK1.4和Oracle数据库。 我正在使用批处理更新,还设置了属性50,但这并没有帮助。 我的对象与另一个对象具有一对一的关系,因此在这种情况下使用StatelessSession可能会出现问题。

  • 问题内容: 如何保存休眠实体并忽略(不正确)瞬态模式。 例如: 我想保存它: 弹簧产生错误: 问题答案: 参见http://docs.jboss.org/hibernate/validator/4.2/reference/en- US/html_single/#validator-checkconstraints- orm 。默认情况下,Hibernate(ORM)检查默认验证组的每个约束。因此,

  • 问题内容: 我已经读到,使用hibernate的二级缓存,它可以通过减少对数据/对象检索的数据库命中次数来提高应用程序性能。 但是,hibernate如何确保二级缓存与数据库中的数据保持最新。 例如: 假设下面的类是实体并且持久化到数据库中。 现在,如果我们启用了二级缓存,我知道如果打开不同的会话,则每个会话都将命中二级缓存以获取对象值。 现在,如果数据库中的数据发生更改(例如,对于ID = 1的

  • 问题内容: 我们遇到了遗留代码问题。有一个用于“用户名”字段的验证集,用于验证其长度并确保其至少包含一个字母: 我们面临的问题是,一些现有的旧数据不适合这些验证,我正在尝试找到一种方法,使旧数据(旧用户)可以忽略这些验证,同时仍将这些验证应用于新创建的用户。 我正在考虑将验证移至方法(因此将仅在实际更改时验证值),但这导致了异常: 我还确保将实体设置为,但这无济于事,因为hibernate会验证所

  • 当对象变脏(已修改)时,是否有方法强制hibernate在saveOrUpdate上保存对象的新实例(新标识符)?这是否可以通过配置或拦截器实现?我有三个实体: 基本上,我希望C在创建和保存B时始终保存B的快照,而不是直接引用a引用的B实例。 B应该是可修改的,A应该指向B的最新版本。 我可以通过实现equals方法手动实现这一点,在调用saveOrUpdate()之前检查equals并在必要时将

  • 无论如何,如果用户名已经被使用,存储库只需进行更新,因为指定的标识符不是空的。这不是我想要的行为,我需要它抛出类似重复条目异常的东西。有什么办法可以预防吗?我必须自己做吗?例如: