今天在写代码的时候又遇到了关于hibernate的操作,因为一直没有系统的学过hibernate做起来还是有些吃力。各种百度各种Google,记得以前也这样做过只不过没把当时的学到的、了解到的记录下来,看过就忘了。为了不再重蹈覆辙,今天要把遇到的问题及解决方法,网上搜罗到的知识在这里汇总一下。一,是为了加深对这些知识的掌握,二,如果能帮到遇到同样问题的朋友就更好了。话不多说,上菜。
因为遇到的问题算是解决了(可能还会出现新的问题),还原现场,且听我娓娓道来。
第一阶段,拿起代码就是写。
大体逻辑:将对象保存到数据库,如果数据库中有此对象(根据唯一约束)则更新。听起来没毛病。
public void addAwosList(List<AwosDto> awosDtos) {
if (awosDtos.size() == 0) return;
for (AwosDto awosDto : awosDtos) {
Awos awos = new Awos(); //瞬时态
BeanUtils.copyProperties(awosDto, awos);
if(awosDao.findByReportIDAndRno(awos.getReportId(),awos.getRno()) == null){
awosDao.add(awos); //变为持久态
}else{
awosDao.update(awos);
}
}
}
执行,第一个错误来了,直译一下,hibernate瞬时态对象异常:你给的对象有空的标识符(真不能直译)。简单来说就是没有主键。这时候,我们就见识到了hibernate的冰山一角,瞬时态。
Caused by: org.hibernate.TransientObjectException: The given object has a null identifier
第二阶段,小失落
没有主键还不好办,那就加上呗
public void addAwosList(List<AwosDto> awosDtos) {
if (awosDtos.size() == 0) return;
for (AwosDto awosDto : awosDtos) {
Awos awos = new Awos();
BeanUtils.copyProperties(awosDto, awos);
if(awosDao.findByReportIDAndRno(awos.getReportId(),awos.getRno()) == null){
awosDao.add(awos);
}else{
Long id =
awosDao.findByReportIDAndRno
(awos.getReportId(),awos.getRno()).
getId();
awos.setId(id);
awosDao.update(awos);
}
}
}
执行,第二个错误,接着直译,非唯一对象异常:一个有着同样标识符的对象已经与Session绑定了。到了这里就有点头大了。我们又见识到了冰山的另一角,Session.
既然说已经在session中存在,那就直接在session中更改并提交。
org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session
第三阶段,各种搜索
让我们从三种状态说起,transient (瞬时态)、persistent(持久态)、detached(游离态)。
官方文档见Chapter 10. Working with objects
- 瞬时态 是一个对象刚通过new操作被实例化,还没有关联Session,没有在数据库中持久化表示也没有被分配标识符(说人话,就是TMD这个实例在数据库中没有对应的存在也没有分配主键)。主键分类
Cat cat = new Cat();
cat.setName("大橘");
//在这里cat就属于瞬时态
- 持久态 持久态实例存在于数据库中也有主键,它与Session相关联,Session 具有一个缓存, 位于缓存中的对象称为持久化对象, 它和数据库中的相关记录对应。我们可以通过关联Session来把一个瞬时态变为持久态。
Long id = (Long)session.save(cat);//具体返回什么,要看代码
//cat现在就属于持久态了
- 游离态 是一个对象已经被持久化(存到数据库),但是Session被关闭了。它的引用依然有效,当然也能修改(
cat.setName("小花")
)
说了这么多有什么用呢,其实还是有的,至少知道了一个对象是处于什么状态。但还是不能直接解决上述问题啊
更新中….