`
lgstarzkhl
  • 浏览: 335202 次
  • 性别: Icon_minigender_1
  • 来自: 沈阳
社区版块
存档分类
最新评论

Hibernate 疑难异常及处理

    博客分类:
  • orm
阅读更多
1、a different object with the same identifier value was already associated with the session。
  错误原因:在hibernate中同一个session里面有了两个相同标识但是是不同实体。
  解决方法一:session.clean()
  PS:如果在clean操作后面又进行了saveOrUpdate(object)等改变数据状态的操作,有可能会报出"Found two representations of same collection"异常。
  解决方法二:session.refresh(object)
  PS:当object不是数据库中已有数据的对象的时候,不能使用session.refresh(object)因为该方法是从 hibernate的session中去重新取object,如果session中没有这个对象,则会报错所以当你使用saveOrUpdate (object)之前还需要判断一下。
  解决方法三:session.merge(object)
  PS:Hibernate里面自带的方法,推荐使用。
2、Found two representations of same collection
  错误原因:见1。
  解决方法:session.merge(object)

以上两中异常经常出现在一对多映射和多对多映射中。
3、net.sf.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing:  BBusinessman
从这个bug的字面上,应该是BBusinessman的某个属性是一个实体,在这个实体没有保存之前就保存Businessman对象,导致的错误。所以我就一直看Businessman的属性中到底哪个是实体,结果发现三个,分别City , Type, Status,而且这三个实体都是dao.load( Id , Session)从数据库中获得的,不是已经有Id的,或者是null,而不存在没有保存的实体。

于是我又怀疑,是否是同一个事务需要一个session,如果不使用此session,是不是这个原因,于是我把事务中方法里所有dao.getSession()这样不太明确的地方都是用方法传入的session,这样session都是同一个了,但是仍旧有此错误。

这样,BBusinessman的各个属性都是没有问题的。那么是否是没有保存BBusinessman之前,而且BBusinessman又被当作某个实体的属性,首先保存此实体,然后去保存BBusinessman,这样是否会导致这个错误。结果我发现,正是这个问题。

================错误的写法:===================

Session session = dao.getSession();

Transaction tx = session.beginTransaction();

Bo.setBman( form ,man,session);

Bo.saveChangeTable( man,session); // 把man当作属性赋给ChangeTable,并保存ChangeTable. 就是这出的错,

dao.save(man,session);  // 保存man

tx.commit();

==================== 应该这样写:===============

Session session = dao.getSession();

Transaction tx = session.beginTransaction();

Bo.setBman( form ,man,session);

dao.save(man,session);  // 保存man

Bo.saveChangeTable( man,session); // 把man当作属性赋给ChangeTable,并保存ChangeTable. 就是这出的错,

tx.commit();

这样,问题就解决了。



4、Write operations are not allowed in read-only mode (FlushMode.NEVER) - turn your Session into FlushMode.AUTO or remove 'readOnly' marker from transaction definition 错误解决

错误代码:
  org.springframework.dao.InvalidDataAccessApiUsageException: Write operations are not allowed in read-only mode (FlushMode.NEVER) - turn your Session into FlushMode.AUTO or remove 'readOnly' marker from transaction definition
错误原因:
  OpenSessionInViewFilter在getSession的时候,会把获取回来的session的flush mode 设为FlushMode.NEVER。然后把该sessionFactory绑定到TransactionSynchronizationManager,使request的整个过程都使用同一个session,在请求过后再接除该sessionFactory的绑定,最后closeSessionIfNecessary根据该session是否已和transaction绑定来决定是否关闭session。在这个过程中,若HibernateTemplate 发现自当前session有不是readOnly的transaction,就会获取到FlushMode.AUTO Session,使方法拥有写权限。
也即是,如果有不是readOnly的transaction就可以由Flush.NEVER转为Flush.AUTO,拥有insert,update,delete操作权限,如果没有transaction,并且没有另外人为地设flush model的话,则doFilter的整个过程都是Flush.NEVER。所以受transaction保护的方法有写权限,没受保护的则没有。
参考文章:
  http://calvin.blog.javascud.org/post/46.htm
解决办法:
  采用spring的事务声明,使方法受transaction控制
<bean id="baseTransaction"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
          abstract="true">
        <property name="transactionManager" ref="transactionManager"/>
        <property name="proxyTargetClass" value="true"/>
        <property name="transactionAttributes">
            <props>
                <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
                <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
                <prop key="load*">PROPAGATION_REQUIRED,readOnly</prop>
                <prop key="save*">PROPAGATION_REQUIRED</prop>
                <prop key="add*">PROPAGATION_REQUIRED</prop>
                <prop key="update*">PROPAGATION_REQUIRED</prop>
                <prop key="remove*">PROPAGATION_REQUIRED</prop>
            </props>
        </property>
    </bean>
    <bean id="userService" parent="baseTransaction">
        <property name="target">
            <bean class="com.phopesoft.security.service.impl.UserServiceImpl"/>
        </property>
    </bean>


5、关于Hibernate的 Batch update returned unexpected row count from update异常

ERROR [http-8080-Processor22] (BatchingBatcher.java:60) - Exception executing batch:
org.hibernate.StaleStateException: Batch update returned unexpected row count from update: 0 actual row count: 0 expected: 1



1).使用的是hibernate的saveOrUpdate方法保存实例。saveOrUpdate方法要求ID为null时才执行SAVE,在其它情况下执行UPDATE。在保存实例的时候是新增,但你的ID不为null,所以使用的是UPDATE,但是数据库里没有主键相关的值,所以出现异常。


=================================================================

异常:
在插入时:
org.hibernate.StaleStateException: Batch update returned unexpected row count from update: 0 actual row count: 0 expected: 1


解决方法:
如果是自增主键?
有的数据库是可以修改自增主键例如:mysql,有的数据库是不允许修改自增主键的例如postgresql
不要设置自增主键的值



2)

在Hibernate映射一对多,多对一,多对多的时候新增常常会出现这个异常,代码如下:

public void saveFunctionCell(FunctionCell functionCell, Integer pid) {
  System.out.println("现在进行新增操作");
  FunctionCell fc = new FunctionCell();
    try {
   BeanUtils.copyProperties(fc, functionCell);
  } catch (IllegalAccessException e) {
   e.printStackTrace();
  } catch (InvocationTargetException e) {
   e.printStackTrace();
  }
  fc.setFuncCellID(null);
  // 获得父权限
  FunctionCell pfc = functionCellDao.findFunctionCellByID(pid);
  fc.setParentFunctionCell(pfc);
  functionCellDao.saveFunctionCell(fc);
}

注意特别标识出来的这个地方,BeanUtils拷贝Bean属性的时候,它会将你的Integer类型全部设置成0,在这里设置一个空,这样就不会抛出错误了。

分享到:
评论

相关推荐

    hibernate 常见异常

    本文将深入探讨Hibernate常见的异常,以及与之相关的依赖库。 首先,我们看到的`java.lang.NoClassDefFoundError`是一个典型的运行时异常,表示在类加载时找不到对应的类定义。这通常意味着在编译时存在所需的类,...

    hibernate常见异常

    Hibernate 常见异常处理 Hibernate 是一个流行的 Java 持久层框架,但是在实际开发中,我们经常会遇到各种异常。了解这些异常的原因和解决方案是非常重要的。本文将介绍 Hibernate 中的一些常见异常,包括 ...

    hibernate常见问题及处理.doc

    在使用Hibernate进行Java持久化操作时,可能会遇到各种异常,这些异常通常是由于配置错误、对象状态管理不当或映射文件不匹配等原因导致的。以下针对给出的常见异常进行详细解释和处理方法: 1. `...

    Java_Jdbc_Hibernate_Struts2_Android_Web异常及其处理办法

    在遇到异常时,程序员可以通过`try-catch`块捕获并处理异常,`finally`块确保某些代码(如资源清理)无论是否发生异常都会执行。如果一个方法可能会抛出异常但不想在当前方法中处理,可以使用`throws`声明异常。 1....

    详解Hibernate事务处理机制

    ### 详解Hibernate事务处理机制 #### 一、引言 Hibernate作为一款优秀的对象关系映射(ORM)框架,在Java开发领域扮演着极其重要的角色。它不仅简化了数据持久化的复杂性,还提供了一系列强大的功能来支持高效的...

    Hibernate下数据批量处理解决方案

    在Java开发中,尤其是涉及到大数据量的处理时,人们往往会质疑ORM框架,如Hibernate,是否适合进行批量数据操作。然而,实际上,通过适当的技术手段,我们可以有效地解决Hibernate在批量处理时可能出现的性能问题。...

    hibernate动态映射表处理oracle的clob类型

    7. **异常处理**:在处理CLOB时,可能会遇到如`DataTruncation`、`SQLTimeoutException`等异常,需要适当地捕获并处理。 8. **版本控制**:在Oracle 10g中,如果你的表有版本控制(如通过TIMESTAMP列实现),则在...

    Spring Hibernate 事务处理 详细说明

    当Spring和Hibernate结合使用时,Spring负责事务的外部管理,而Hibernate则处理内部的数据库交互。Spring通过透明地管理Hibernate的Session,确保事务的正确性。这种模式被称为JPA(Java Persistence API)的“容器...

    hibernate异常文档.xls

    hibernate异常文档.xls hibernate异常文档.xls

    Hibernate,hibernate笔记

    Hibernate 是一个开源的对象关系映射(ORM)框架,它允许...理解和熟练使用Hibernate配置、异常处理、HQL查询以及IDE集成是每个Java开发者必备的技能。通过上述步骤,你可以更好地了解和应用Hibernate进行数据库操作。

    struts2+hibernate实现登录及增删改操作

    综上所述,"struts2+hibernate实现登录及增删改操作"涉及到的是如何利用这两个框架构建一个完整的Java Web应用,包括用户身份验证、数据库操作以及对数据的增删改等核心功能。这个小案例可以帮助开发者理解并熟练...

    Hibernate映射导致的几个异常

    标题与描述概述的知识点主要集中在Hibernate映射过程中可能遇到的各种异常情况,这涉及到数据库与对象模型之间的映射问题,以及Hibernate框架在处理这些映射时可能产生的错误。下面将对这些异常进行详细的解释和分析...

    Hibernate做的留言板

    【标题】"Hibernate做的留言板" 是一个基于Java的Web应用程序,使用了流行的持久化框架Hibernate来处理数据库交互。这个项目提供了完整的源代码,方便开发者直接在Eclipse集成开发环境中运行和学习。它不仅是一个...

    在Java SE中使用Hibernate处理数据

    在Java SE环境中使用Hibernate处理数据是一项常见的任务,尤其是在开发企业级应用时,需要对数据库进行高效、灵活的管理和操作。Hibernate作为一个流行的Object-Relational Mapping(ORM)框架,能够简化Java程序员...

    Hibernate的事务处理机制和flush方法的用法.docx

    在本文中,我们将深入探讨Hibernate的事务处理机制以及`flush`方法的用法,并分析为何在某些场景下会出现特定的异常。 首先,我们需要了解Hibernate中的事务处理。在Java应用中,事务通常与SessionFactory和Session...

    hibernate aip hibernate aip

    9. **错误处理和日志记录**:理解Hibernate常见的错误和异常,如 detached entity passed to persist 等,并配置合适的日志系统,如Log4j或SLF4J,以便追踪应用运行状态。 总的来说,Hibernate AIP涵盖了从项目初始...

    hibernate3.2lib及源码jar包纯净版

    **hibernate3.2lib及源码jar包纯净版** Hibernate是一个开源的Java平台上的对象关系映射(ORM)框架,它允许开发者将数据库操作转换为对Java对象的操作,从而简化了数据库应用的开发。这个标题指的是一个针对...

    Hibernate入门到精通

    Hibernate 的主要特点是:支持多种数据库管理系统、提供了高效的数据访问机制、支持事务处理和缓存机制等。 Hibernate 环境搭建 要使用 Hibernate,首先需要搭建 Hibernate 的开发环境。下面是 Hibernate 环境搭建...

    hibernate的大部分的工具类

    在描述中提到的“判断是否为空的工具类”,可能是为了确保在处理数据时避免因为空值引发的异常。这类工具类通常包含如`isEmpty`或`isNullOrEmpty`这样的方法,它们用于检查集合、字符串或其他对象是否为空或null。这...

    2022年Hibernate下数据批量处理Java教程.docx

    Hibernate 下数据批量处理 Java 教程 本文主要介绍了使用 Hibernate 实现数据批量处理的方法和注意事项。在 Java 中,对数据批量处理的需求非常重要,但许多人对 Java 是否适合批量处理持有怀疑念头。实际上,如果...

Global site tag (gtag.js) - Google Analytics