分享
分销 收藏 举报 申诉 / 8
播放页_导航下方通栏广告

类型收集:Hibernate中常见问题-No-row-with-the-given-identifi.docx

  • 上传人:仙人****88
  • 文档编号:11825144
  • 上传时间:2025-08-14
  • 格式:DOCX
  • 页数:8
  • 大小:30.84KB
  • 下载积分:10 金币
  • 播放页_非在线预览资源立即下载上方广告
    配套讲稿:

    如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。

    特殊限制:

    部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。

    关 键  词:
    收集 Hibernate 常见问题 No row with the given identifi
    资源描述:
    Hibernate中常见问题 No row with the given identifier exists问题的原因及解决 产生此问题的原因: 有两张表,table1和table2. 产生此问题的原因就是table1里做了关联<one-to-one>或者<many-to-one unique="true">(特殊的多对一映射,实际就是一对一)来关联table2.当hibernate查找的时候,table2里的数据没 有与table1相匹配的,这样就会报No row with the given identifier exists这个错.(一句话,就是数据的问题!) 假如说,table1里有自身的主键id1,还有table2的主键id2,这两个字段.   如果hibenrate设置的单项关联,即使table1中的id2为null值,table2中id2中有值,查询都不会出错.但是如果table1中的id2字段有值,但是这个值在table2中主键值里并没有,就会报上面的错! 如果hibernate是双向关联,那么table1中的id2为null值,但是table2中如果有值,就会报这个错.这种情况目前的解决办法就是改成单项关联,或者把不对应的数据改对! 这就是报这个错的原因了,知道原因了就相应的改就行了.或许还有些人迷惑hibernate关联都配好了,怎么会出现这样的错?其实这是编程的时候出现的 问题,假如说我在添加信息的时候,页面传过来的struts的formbean到dao方法中需要封装成hibernate的po(就是 hibenrate的bean),要是一个个po.get(form.set())实在太麻烦了,这样一般都会写个专门的方法来封装,遇到 po.get(form.set())这种情况直接把struts的formbean对象传到此方法中封装就行了,假如我有个字段是创建人id,那么这个 字段是永远不会改的,我在添加的时候还调用这个方法,这个专门封装的方法是有一些判断的,假如说我判断一下,如果遇到创建人id传过来为空值,我判断如果 是空值,我把创建人id设为0,但是用户表中userid是主键从1开始自增的,那么这样数据就对应不上了,一查就会出这个错了.这个错在开发刚开始的时 候经常发生,因为每个人的模块都是由相应的人独立开发完成以后再整合在一起的,每个人写单独那一块的时候往往会忽略这些,所以整合的时候这些问题往往就都 一下子全冒出来了....整合很辛苦,tnnd!     hibernate的查询的比较 hibernate的查询有很多,Query,find,Criteria,get,load query使用hsql语句,可以设置参数是常用的一种方式 criteria的方式,尽量避免了写hql语句,看起来更面向对象了。 find方式,这种方式已经被新的hibernate丢弃 get和load方式是根据id取得一个记录 下边详细说一下get和load的不同,因为有些时候为了对比也会把find加进来。 1,从返回结果上对比: load方式检索不到的话会抛出org.hibernate.ObjectNotFoundException异常 get方法检索不到的话会返回null 2,从检索执行机制上对比: get方法和find方法都是直接从数据库中检索 而load方法的执行则比较复杂 1,首先查找session的persistent Context中是否有缓存,如果有则直接返回 2,如果没有则判断是否是lazy,如果不是直接访问数据库检索,查到记录返回,查不到抛出异常 3,如果是lazy则需要建立代理对象,对象的initialized属性为false,target属性为null 4, 在访问获得的代理对象的属性时,检索数据库,如果找到记录则把该记录的对象复制到代理对象的target 上,并将initialized=true,如果找不到就抛出异常 。 java.lang.IllegalArgumentException: node to traverse cannot be null! 错误原因:       通常此类错误都是由于HQL语句写的不正确,例如from写成了form,或者set A = 1 and B = 2,其中set不同字段用逗号","分离而不是用and.总之仔细检查HQL语句,看看有没有语法错误即可. ids for this class must be manually assigned before calling save().. org.hibernate.id.IdentifierGenerationException: ids for this class must be manually assigned before calling save():   引起问题的原因: 由Hibernate根据数据库表自动生成的"类名.hbm.xml"映射文件引起的。 首先我的表(Info)由两个字段组成,即: int id;//主建 String name; (自己做测试,所以就简单的建了个表) 由Hibernate生成的Info.hbm.xml中是这样写的: ----------------------------------------------------- <id name="id" type="java.lang.Integer">             <column name="id" />             <generator class="assigned"/> </id> ----------------------------------------------------- <id>这个是必须有的。它是用来定义实体的标识属性(对应数据库表的主键) 而我这里由于id本身就是主键,所以column的属性便是id 下面是很关键的一点<generator>,由于一时兴趣,于是找了很多资料,关于它的解释是:用于指定主键的生成策略。它的值有多,下面是转来的: -------------------------------------------------------------------------------- “assigned” 主键由外部程序负责生成,在   save()   之前指定一个。     “hilo” 通过hi/lo   算法实现的主键生成机制,需要额外的数据库表或字段提供高位值来源。     “seqhilo” 与hilo   类似,通过hi/lo   算法实现的主键生成机制,需要数据库中的   Sequence,适用于支持   Sequence   的数据库,如Oracle。     “increment” 主键按数值顺序递增。此方式的实现机制为在当前应用实例中维持一个变量,以保存着当前的最大值,之后每次需要生成主键的时候将此值加1作为主键。这种方式可能产生的问题是:不能在集群下使用。     “identity” 采用数据库提供的主键生成机制。如DB2、SQL   Server、MySQL   中的主键生成机制。     “sequence” 采用数据库提供的   sequence   机制生成主键。如   Oralce   中的Sequence。     “native” 由   Hibernate   根据使用的数据库自行判断采用   identity、hilo、sequence   其中一种作为主键生成方式。     “uuid.hex” 由   Hibernate   基于128   位   UUID   算法   生成16   进制数值(编码后以长度32   的字符串表示)作为主键。     “uuid.string” 与uuid.hex   类似,只是生成的主键未进行编码(长度16),不能应用在   PostgreSQL   数据库中。       “foreign” 使用另外一个相关联的对象的标识符作为主键。 -------------------------------------------------------------------------------- 看了上面的介绍,再看看代码,原来是<Generator>属性设置有问题。 然后改为"identity"、"native"问题便解决。 使用Hibernate设计Dao层的几种方式     直接奔主题,说一说数据库访问层的问题,该层操作数据库的实现方式有很多种,当然各有各的好处,选择哪一种,根据你的心情而定,dao层所做的事情就是单纯的数据CRUD,不做别的事情,如果你发现你的dao层存在业务逻辑,那么赶紧在项目没有做大之前改掉吧,因为我就曾今看到过我以为同学,把DAO层和Service层搞混了,dao存在于大多数软件工程中,它已成为程序架构必不可少的组成部分,当然,dao是可拔插的,如果你的dao写死在了某个程序里,那说明你对于dao的理解并不透彻,试着把你的dao移植到别的程序里吧,如果不能做到“一次编写,到处运行”,那就考虑重构你的dao层吧!  第一种:直接写JDBC来实现数据库的操作,这种方式是最原始的,当然,如果你对于写JDBC非常的熟悉,那没问题,但是这并不是一个追求上进的程序员做的事,久而久之,这将是一件痛苦的事,而不是一件值得炫耀的事……  那么以下的几种方法就是直接通过或间接通过hibernate框架来实现dao层的设计了,因为hibernate够强大,够流行,够灵活,曾经试过使用JBoss写DAO,的确不怎么爽!  第二种:使用hibernate的session实现数据库操作,这种方式是使用hibernate的最基础的方式,也是最灵活的一种方式,因为session实现了hibernate的所有数据库操作方法,剩下的就看你如何组装这些语句完成你的程序逻辑了  第三种:继承Spring的HibernateDaoSupport,Spring为Hibernate的Dao提供的工具类,其底层是通过HibernateTemplate来实现数据库的操作,但是使用这个工具类,有些地方,对于数据库的操作并不够灵活,曾经我为了这些问题纠结了很久,也许是我个人对这个类的熟悉度有限,如果有哪位童鞋能灵活的运用此类,还望指点一二  第四种:使用HibernateTemplate,它提供了非常多的常用方法来完成数据库的基本操作,使得持久层访问摸板化,这种方式其实和第三种差不多,不多做解释,但是要灵活的运用该模板,还得知道第五种方式  第五种:Hibernate的复杂用法HibernateCallback回调函数,通过调用回调函数来实现的数据库操作,这种方式可以完全使用Hibernate的 session操作数据库,这也是我最喜欢用的方法,因为它够强大,够灵活,够高深  第六种:使用EntityManager,EntityManager里也封装了hibernate对数据库的操作,可以通过@PersistenceContext注解为其注入实例,但是本人对于此类的使用方法并不是很熟悉,也只使用过一次而已,还在学习中  以上只是列举了我使用过的DAO层的设计方案,并没有提供具体的实现代码,这里写代码的确不方便,以上的六种实现方式,都有各的好处,也遇到过一些细节上的问题,只有经过更多的人的使用,才可以找到问题,并且去解决问题,对于有意了解使用以上几种方式的详情的童鞋,可以一起讨论讨论,并提供你的实现源码!  如何打破多表关联的关系 在多表关联的关系中,如果要删除其中一个表中的一条子数据,必定与这个表,这条数据有关联的数据也会被删除,但是这样的结果却不是我们要见到的。而我们要的效果是,1.删除子数据,父数据不被删除,与关联的表也不删除。2.删除父数据,而父数据下的子数据,孙子数据也会被删除,而与它关联的表也不删除。而怎样实现这样的结果呢,这就需要我们去打破他们之间的关系了。怎么打破呢,看下面的代码。  ----这是一个个人空间中说说表say的删除代码-----------  发表一条说说,要知道发表说说的人,和回复说说的人,而这俩者都是一个user表里面的。  所以说,这个说说表say是跟用户表user是关联的,用户表跟说说表是一对多的关系。        -------删除父说说------  @Transactional  public boolean deleteFatherSay(Integer sayId) {  Say say = sayDao.findById(sayId);   //获取"父节点"  Iterator<Say> iter = say.getSays().iterator(); //获取"父节点"下的"子节点",并存在迭代器里面  for (int i = 0; i < say.getSays().size(); i++) {//循环遍历每个"子节点"  Say say1 = iter.next();    //获取单个的子节点  Iterator<Say> iter1 = say1.getSays().iterator();  //获取单个"子节点"下"孙子节点",并存在迭代器里面  for (int j = 0; j < say1.getSays().size(); j++) {//循环遍历每个"孙子节点"  Say say2 = iter1.next();    //获取单个的孙子节点  say2.setUser(null);     //打破"孙子节点"与user的关联  say2.setSay(null);      //打破"孙子节点"与"子节点"的关系(删除"孙子节点"时,就不会把与"孙子节点"相关联的"子节点"也删除)  sayDao.delete(say2);     }  say1.setSay(null);  say1.setUser(null);  sayDao.delete(say1);  }  say.setUser(null);  sayDao.delete(say);  return true;  }              ----删除子说说----  @Transactional  public boolean deleteSonSay(Integer sayId) {  Say say = new Say();  say.setSayId(sayId);  String hql = "from Say as say1 where say1.say=" + sayId;  List<Say> list = sayDao.findByHql(hql);  Iterator<Say> iter = list.iterator();  for (int i = 0; i < list.size(); i++) {  Say say1 = iter.next();  say1.setUser(null);  say1.setSay(null);  sayDao.delete(say1);  }  say.setSay(null);  say.setUser(null);  say.setSays(null);  sayDao.delete(say);  return true;  }        ---删除孙子说说---  @Transactional  public boolean deleteGrandsonSay(Integer sayId) {  Say say = sayDao.findById(sayId);  say.setSay(null);  say.setUser(null);  say.setSays(null);  sayDao.delete(say);  return true;  }   ----------结论-----------      如何打破他们的关系,就要知道一点,先打破下层关系,再打破上层的关系,这是自下而上来打破它们间的关系。       父---子---孙子,(说说表say和用户表user有关联,所以say.setUser(null),这样就打破了和用户表之间的关联关系).      1.删除孙子的说说,这要把上层的关系打破就行了say.setSay(null),这样删除孙子说说,就不会删除子说说和父说说。       2.删除子说说(子说说是夹在父说说和孙子说说之间),还是按照自下而上的规则,先找出子说说的所有孙子说说,然后用for循环遍历每一个孙子说说,然后再打破孙子say.setSay(null);say.setUser(null);和上层的关系,最后删除孙子说说,然后子说说在打破和上层父说说的关系say.setSay(null);say.setUser(null);,最后删除子说说,那么子说说下的孙子说说也全部删除,而父说说则不会影响到。       3.删除父说说,那么就要循环删除子说说和孙子说说,及要打破他们各自的关系。删除完父说说的子说说和孙子说说,最后再打破和用户表的关系say.setUser(null).这样就能删除父说说的同时也删除完他下面的说说,而不会影响到用户表user. 
    展开阅读全文
    提示  咨信网温馨提示:
    1、咨信平台为文档C2C交易模式,即用户上传的文档直接被用户下载,收益归上传人(含作者)所有;本站仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。所展示的作品文档包括内容和图片全部来源于网络用户和作者上传投稿,我们不确定上传用户享有完全著作权,根据《信息网络传播权保护条例》,如果侵犯了您的版权、权益或隐私,请联系我们,核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
    2、文档的总页数、文档格式和文档大小以系统显示为准(内容中显示的页数不一定正确),网站客服只以系统显示的页数、文件格式、文档大小作为仲裁依据,个别因单元格分列造成显示页码不一将协商解决,平台无法对文档的真实性、完整性、权威性、准确性、专业性及其观点立场做任何保证或承诺,下载前须认真查看,确认无误后再购买,务必慎重购买;若有违法违纪将进行移交司法处理,若涉侵权平台将进行基本处罚并下架。
    3、本站所有内容均由用户上传,付费前请自行鉴别,如您付费,意味着您已接受本站规则且自行承担风险,本站不进行额外附加服务,虚拟产品一经售出概不退款(未进行购买下载可退充值款),文档一经付费(服务费)、不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
    4、如你看到网页展示的文档有www.zixin.com.cn水印,是因预览和防盗链等技术需要对页面进行转换压缩成图而已,我们并不对上传的文档进行任何编辑或修改,文档下载后都不会有水印标识(原文档上传前个别存留的除外),下载后原文更清晰;试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓;PPT和DOC文档可被视为“模板”,允许上传人保留章节、目录结构的情况下删减部份的内容;PDF文档不管是原文档转换或图片扫描而得,本站不作要求视为允许,下载前可先查看【教您几个在下载文档中可以更好的避免被坑】。
    5、本文档所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用;网站提供的党政主题相关内容(国旗、国徽、党徽--等)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
    6、文档遇到问题,请及时联系平台进行协调解决,联系【微信客服】、【QQ客服】,若有其他问题请点击或扫码反馈【服务填表】;文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“【版权申诉】”,意见反馈和侵权处理邮箱:1219186828@qq.com;也可以拔打客服电话:0574-28810668;投诉电话:18658249818。

    开通VIP折扣优惠下载文档

    自信AI创作助手
    关于本文
    本文标题:收集:Hibernate中常见问题-No-row-with-the-given-identifi.docx
    链接地址:https://www.zixin.com.cn/doc/11825144.html
    页脚通栏广告

    Copyright ©2010-2026   All Rights Reserved  宁波自信网络信息技术有限公司 版权所有   |  客服电话:0574-28810668    微信客服:咨信网客服    投诉电话:18658249818   

    违法和不良信息举报邮箱:help@zixin.com.cn    文档合作和网站合作邮箱:fuwu@zixin.com.cn    意见反馈和侵权处理邮箱:1219186828@qq.com   | 证照中心

    12321jubao.png12321网络举报中心 电话:010-12321  jubao.png中国互联网举报中心 电话:12377   gongan.png浙公网安备33021202000488号  icp.png浙ICP备2021020529号-1 浙B2-20240490   


    关注我们 :微信公众号  抖音  微博  LOFTER               

    自信网络  |  ZixinNetwork