hibernate先删除数据,紧接着执行插入时的异常解决之道——中间不能调用flush()、clear()等方法

  项目中包含这样一个寻常的业务:为某一个用户指定用户群。一个用户可以被分配到多个用户群中,后台管理者可以为该用户分配用户群,并可更新这种分配。在做更新的时候,将所有的用户群都以checkBod的形式显示出来,页面初始化的时候,那些用户已经关联的群的checkBox会被勾选,然后管理员可以重新勾选,重新为该用户指定用户群。

  好了,问题出现了:在重新指定用户群的时候,首先需要删除数据库中原有的一张关系表(该表中储存用户ID和用户群ID)中所有该用户ID的记录,然后再重新将管理员所指定的新的用户群保存进这种关系表中。于是这里至少需要两条sql文——delete()和save()。由于担心在插入数据的时候系统难免会因为某些特殊的偶然的原因而出现故障而导致无法插入,此时就需要保证出现这种情况时,delete()语句执行无效,即delete()之后,不能调用flushu()、clear()、commit()等方法(这些方法会迫使原先对内存中的备份数据的删除操作进一步作用于持久层)。但是这样又会出现新的问题:持久层中的数据不真正删除掉,就无法再插入新的数据,否则会抛出诸如“存在一个与该对象完全相同的另一个对象”之类的异常。这还真是一问题,不过思考了许久之后,还是想出一条锦囊妙计,那就是:先用一个hashmap来保存每一个被删除掉的关系对象和该对象中的用户群的ID(因为用户表语用户群表的关系是一对多的关系),然后在执行插入数据的时候,先判断管理员所勾选的用户群是否也存在于该map中(通过用户群ID来判断),如果是存在,那么也就是该用户群是用户原本就被分配在其中的,那么在开始执行删除的时候,该关系对象已经在内存中被删除掉了,但是真正的持久层中尚未被删除(因为没有调用flush()等方法来强迫执行),那么这时就从map中取出该关系对象,直接执行savaOrUpdate()方法;而如果不存在,则new一个关系对象,然后设置该对象的用户ID和用户群ID属性,然后执行save()方法。OK,一个难题就这样被解决了。

  下面是项目中的该业务部分的代码,以形象地解释上面的萝莉啰唆的文字:

  //保存用户与其所关联的用户群关系(先删除全部记录,再分布保存)
        
        //该哈希表键为用户群ID,值为用户与其所关联的用户群关系对象(UsrGroup)
        HashMap<Long, UsrGroup> map = new HashMap<Long, UsrGroup>();
        
        //先删除该用户所关联的所有用户群记录,并将用户群ID与关系对象保存入哈希表中
        //这是因为执行delete()方法时,未调用flush()方法,故数据库中并未真正删除记录;
        //因此在接下来插入数据时便会报出“对象已存在”之类的异常
        List<UsrGroup> list = usrGroupDao.findByUsrId(HibernateSessionFactory.getSession(), usrId);
        for(int i = 0; i < list.size(); i++){
            usrGroupDao.delete(HibernateSessionFactory.getSession(), list.get(i));
            map.put(list.get(i).getUsrGroupId(), list.get(i));
        }
        
        //再保存被该主题所关联的版块链接
        String[] selectedLinkList = selectedLinkStr.split(",");//这里的selectedLinkStr是管理员为用户所指定的多个用户群ID,ID之间以逗号分隔
        
        for(int i = 0; i < selectedLinkList .length; i++){
            Boolean bool = false;
            long groupId = Long.valueOf(selectedLinkList [i]);
            
            //如果主题关联的链接ID与刚才被删除的关系对象中的链接ID相同,则执行saveOrUpdate()方法
            //这里只能执行这个方法,别的方法都会报出异常
            if (map.containsKey(groupId )) {
                usrGroupDao.save(HibernateSessionFactory.getSession(), map.get(groupId ));
                bool = true;
            }
            
            //如果用户为当前主题关联了之前所未关联的新的版块链接,则new一个关系对象并保持
            if(!bool){
                try{
                    UsrGroup usrGroup= new UsrGroup();
                    usrGroup.setUsrId(topicId);
                    usrGroup.setUsrGroupId(groupId );
                    
                    usrGroupDao.save(HibernateSessionFactory.getSession(), usrGroup);
                } catch(Exception e){
                    e.printStackTrace();
                }
            }
        }

hibernate先删除数据,紧接着执行插入时的异常解决之道——中间不能调用flush()、clear()等方法...相关推荐

  1. jquery ajax 不执行success,jQuery通过ajax方法获取json数据不执行success的原因及解决方法...

    1.jquery通过ajax方法获取json数据不执行success回调 问题描述:jquery通过ajax方法获取json数据不执行success回调方法 问题原因:json格式存在问题或不符合标准 ...

  2. mysql删除数据后id自增不连续的解决方法

    mysql删除数据后id自增不连续的解决方法 参考文章: (1)mysql删除数据后id自增不连续的解决方法 (2)https://www.cnblogs.com/weifeng-888/p/1163 ...

  3. Atitit.软件GUI按钮与仪表盘--db数据库区--导入mysql sql错误的解决之道

    Atitit.软件GUI按钮与仪表盘--db数据库区--导入mysql sql错误的解决之道 Keyword::截取文本文件后部分 查看提示max_allowed_packet限制 Target Se ...

  4. jpa和hibernate_使用JPA和Hibernate有效删除数据

    jpa和hibernate 您可能会遇到必须对关系数据库中存储的大量数据集执行批量删除的情况. 如果您将JPA与Hibernate一起用作基础OR映射器,则可以尝试通过以下方式调用EntityMana ...

  5. TOAD FOR MYSQL 进行数据插入时乱码的解决办法---MariaDB 5.5

    最近使用mysql是发现插入的数据乱码,几经周折终于找到的解决方法,特作备忘. 开始有将mysql的字符集全部设置成utf8,如下: SHOW VARIABLES LIKE 'character_se ...

  6. jQuery通过ajax方法获取json数据不执行success的原因及解决方法

    1.jquery通过ajax方法获取json数据不执行success回调 问题描述:jquery通过ajax方法获取json数据不执行success回调方法 问题原因:json格式存在问题或不符合标准 ...

  7. win11玩游戏时输入法总是弹出来怎么办? win11打游戏时输入法异常解决办法

    最近在用Win11系统玩游戏的时候,有些用户遇到了输入法总是弹出的问题.这可能是我们的输入法和游戏不兼容造成的.一般来说,可以通过修改英文输入法来解决.让我们一起试试. 很多小伙伴在使用win11系统 ...

  8. 使用JPA和Hibernate有效删除数据

    您可能会遇到必须对关系数据库中存储的大量数据集执行批量删除的情况. 如果您将JPA与Hibernate一起用作基础OR映射器,则可以尝试通过以下方式调用EntityManager的remove()方法 ...

  9. MYSQL数据库删除数据后重新插入数据 id不连续问题

    问题:在删除自增id的表的数据后,再次添加数据会从上次添加的最后一个id开始自增. 解决办法: 重置自增ID sql: alter table 表名 auto_increment=数字 //设置sys ...

最新文章

  1. zigbee学习之路(二)点亮LED
  2. Oracle通过OCI批量加载需要注意的问题
  3. php 数据接口,初识 php 接口
  4. Docker版本介绍(5)
  5. CSS的样式小计(1)
  6. mybatisplus中的xml如何添加like条件,进行模糊查询
  7. [投稿]Speex回声消除代码分析
  8. #pragma once 与 #ifndef 解析(转载)
  9. (响应式PC端媒体查询)电脑屏幕分辨率尺寸大全
  10. 毕设题目:Matlab语音加密
  11. 【旧文章搬运】PsVoid中IrpCreateFile函数在Win7下蓝屏BUG分析及解决
  12. x10I pC套件 官方网站下载
  13. matlab图例双字体设置
  14. python爬取贴吧网页信息
  15. UE4 制作灯光秀的灯光阵列和动画
  16. 有限等距性质RIP理解
  17. 用山脊图展示后验分布
  18. 基本函数依赖和候选键_[总结]关系数据库设计基础(函数依赖、无损连接性、保持函数依赖、范式、……)...
  19. DC-DC升压变换器 直流隔离 高压稳压输出 电源模块
  20. php 检测数组内是否有空值,判断PHP数组是否为空的代码

热门文章

  1. 2022浙江省网络安全技能赛决赛
  2. 记录一次linux服务器被挖矿的解决
  3. android获取固定uuid,稳定获取Android设备唯一代码(UUID)的解决方案
  4. Linux操作系统管理公共基础——积累
  5. Mybatis_Plus日常开发遇到问题
  6. linux下Nginx部署前后端项目
  7. 计算机网络有线通信媒体,传输媒体
  8. “宏”在开发中的使用
  9. Multisim仿真KP12-2高频头本振电路
  10. jvm(java虚拟机)线程堆栈jstack(2)