hibernate在分层架构中修改数据(update)时遇到的问题!!

简介: hibernate在分层架构中修改数据(update)时遇到的问题!!

开发软件:Myeclipse 10.0


      数据库:oracle


      开发人员:1111


      问题简单描述:修改数据的时候不能正常修改,要么修改不成功,要么报错


 nice,下面就来看看怎么解决这个bug的。


       首先,我做的是一个租房网站,进去之后显示的是所有的房屋信息,然后可以对相应的房屋信息进行修改和删除:


让图来解释:20170308000724235.png接下来我的思路是,当点击修改的时候,会进入修改房屋信息的界面updateHouse.jsp,根据改房屋的id,进行查询,显示在update.jsp的表单里面,然后对其的值进行修改!

11.png



到这里都没问题,接下来就开始修改,然后我就改动几个值进行提交:

12.png


开始运行,运行到完之后控制台里面报错:


org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [cn.bdqn.house.entity.House#1085]


     行,你说啥就是啥,你说报错我就解决呗,还能怎么样,我就是干这活的。


一看到这错误,,,这啥错啊,没见过,不会在在网上查,网上说是session中有2个oid一样的对象,hibernate不知道该让哪个持久化到库里,说的不假,我确实是根据id进行数据修改的,此时的session里面有两个一模一样的id,先看一下我的代码:


Daoimpl层:


/**
   * 修改房屋信息
   */
  @Override
  public Object updateHouse(House house) {
    tx=session.beginTransaction();
    try {
      session.update(house);
      tx.commit();
    } catch (HibernateException e) {
      e.printStackTrace();
      tx.rollback();
    }finally{
      session.clear();
    }
    return house;
  }


再看Servlet里面的代码:

1. privateprivate void updateHouseById(HttpServletRequest request, HttpServletResponse response) throws IOException{
    Integer houseId=Integer.parseInt(request.getParameter("houseId"));
    House house=new House();
    PrintWriter out = response.getWriter();
    String title=request.getParameter("title");                         //房屋标题
    Integer typeid=Integer.parseInt(request.getParameter("type_id"));   //房屋类型
    types.setId(typeid);
    Integer floorage=Integer.parseInt(request.getParameter("floorage"));//房屋面积
    Integer price=Integer.parseInt(request.getParameter("price"));      //价格
    String date=request.getParameter("pubdate");                        //发布日期
    SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd");         
    Date pubdate=null;
    try {
      pubdate = format.parse(date);
    } catch (ParseException e) {
      e.printStackTrace();
    }
    Integer  district_id=Integer.parseInt(request.getParameter("district_id")); //区县
    district.setId(district_id);
    Integer street_id=Integer.parseInt(request.getParameter("street_id"));      //街道
    street.setId(street_id);
    String contact=request.getParameter("contact");                             //联系人
    String description=request.getParameter("description");                     //详细描述
    //添加当前登录的用户
    String username=request.getParameter("user");                               //当前的用户
    users.setName(username);
    List<Users> usersList=usersService.getUsersIdByName(users);
    users.setId(usersList.get(0).getId());
    house.setId(houseId);
    house.setTitle(title);
    house.setTypes(types);
    house.setFloorage(floorage);
    house.setPrice(price);
    house.setPubdate(pubdate);
    house.setStreet(street);
    house.setContact(contact);
    house.setDescription(description);
    house.setUsers(users);
    Object object=houseService.updateHouse(house);
    if(object==null){
      out.print("<script>alert('修改失败,请检查填入信息是否正确!');location.href='houseInfoServlet?tag=updateHouse';</script>");
    }else {
      out.print("<script>alert('修改成功!');location.href='houseInfoServlet?tag=guanli';</script>");
    }


原因找到了,但是怎么解决呢?这是个大问题,既然说是session里面有两个id的话,那我就干掉一个试试管用不管用:

 于是,Daoimpl里面的代码就改成了:

13.png


接着运行,看看怎么样


呵呵。报错:org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [cn.bdqn.house.entity.House#1085]


    于是想,session中有个方法是saveOrUpdate(),存在就修改,不存在就添加,试一下看看怎么样:

14.png

运行完一看,还是报错的它,以此分析,house对象里面肯定有值,要不然报的不是这个错。既然哈市报错,那就继续解决,生活就是不断的解决bug,解决一个又出来一个,接着解决!!


    那我在创建一个house对象试试看,把这个house直接赋值给新对象,看看会出现什么!


    好   继续改:


14.png


运行完之后接着给我报同样的错,其实这种方法我本来就绝的不对,报错是自然的,就是想看看。。。。。

   既然update   saveOrupdate   都不行,忽然想到最后一种,用merge试试,他也是修改,看看会怎么样15.png


接着运行,

16.png

OK   解决掉了。


    下面来看看merge()和update()


以下的内容摘抄自网上:

 当我们使用update的时候,执行完成后,我们提供的对象A的状态变成持久化状态。

 但当我们使用merge的时候,执行完成,我们提供的对象A还是脱管状态,hibernate或者new了一个B,或者检索到 一个持久对象B,并把我们提供的对象A的所有的值拷贝到这个B,执行完成后B是持久状态,而我们提供的A还是托管状态。









































20170308000724235.png20170308000724235.png

相关文章
|
2月前
|
存储 SQL 关系型数据库
ClickHouse(02)ClickHouse架构设计介绍概述与ClickHouse数据分片设计
ClickHouse的核心架构包括执行过程和数据存储两部分。执行过程涉及Parser与Interpreter解析SQL,通过Column、DataType、Block、Functions和Storage模块处理数据。Column是内存中列的表示,Field处理单个值,DataType负责序列化和反序列化,Block是内存中表的子集,Block Streams处理数据流。Storage代表表,使用不同的引擎如StorageMergeTree。数据存储基于分片和副本,1个分片由多个副本组成,每个节点只能拥有1个分片。
211 0
ClickHouse(02)ClickHouse架构设计介绍概述与ClickHouse数据分片设计
|
22天前
|
存储 关系型数据库 数据库
数据的反规范化架构
【6月更文挑战第13天】 本文介绍数据库设计包括规范化和反规范化。优化设计和应用规范化规则确保高效且准确的数据存储。
35 2
数据的反规范化架构
|
7天前
|
存储 SQL BI
深入解析实时数仓Doris:介绍、架构剖析、应用场景与数据划分细节
深入解析实时数仓Doris:介绍、架构剖析、应用场景与数据划分细节
|
10天前
|
Java 数据库连接 API
“论数据访问层设计技术及其应用”写作框架,系统架构设计师
在信息系统的开发与建设中,分层设计是一种常见的架构设计方法,区分层次的目的是为了实现“高内聚低耦合”的思想。分层设计能有效简化系统复杂性,使设计结构清晰,便于提高复用能力和产品维护能力。一种常见的层次划分模型是将信息系统分为表现层、业务逻辑层和数据访问层。信息系统一般以数据为中心,数据访问层的设计是系统设计中的重要内容。数据访问层需要针对需求,提供对数据源读写的访问接口;在保障性能的前提下,数据访问层应具有良好的封装性、可移植性,以及数据库无关性。
“论数据访问层设计技术及其应用”写作框架,系统架构设计师
|
28天前
网络编程中的互联网协议 , IP地址 , 域名 , 端口 , 架构 , 网页数据请求 , 响应码
网络编程中的互联网协议 , IP地址 , 域名 , 端口 , 架构 , 网页数据请求 , 响应码
|
7天前
|
存储 消息中间件 负载均衡
技术心得记录:架构设计之数据分片
技术心得记录:架构设计之数据分片
|
13天前
|
XML 前端开发 JavaScript
后端请求响应和分层解耦web开发的三层架构
后端请求响应和分层解耦web开发的三层架构
17 0
|
15天前
|
机器学习/深度学习 数据采集 人工智能
【机器学习】CLIP模型在有限计算资源下的性能探究:从数据、架构到训练策略
【机器学习】CLIP模型在有限计算资源下的性能探究:从数据、架构到训练策略
162 0
|
29天前
|
存储 缓存 NoSQL
了解Redis,第一弹,什么是RedisRedis主要适用于分布式系统,用来用缓存,存储数据,在内存中存储那么为什么说是分布式呢?什么叫分布式什么是单机架构微服务架构微服务的本质
了解Redis,第一弹,什么是RedisRedis主要适用于分布式系统,用来用缓存,存储数据,在内存中存储那么为什么说是分布式呢?什么叫分布式什么是单机架构微服务架构微服务的本质
|
2月前
|
存储 消息中间件 Kafka
数据仓库分层架构
【5月更文挑战第21天】一个数据仓库的分层架构,包括缓冲层、操作数据层、明细数据层、汇总数据层和数据集市层。