这篇文章主要是对Hibernate中的一些知识点重点描述一下,也是自身亲身体会到的知识,因为这是在很多面试的时候都会问到的,而且还用用Hibernate与Mybatis进行比较,所以,对Hibernate其中的一些内容和原理都是需要进行了解的了。
1:进行更新操作的时候,为什么一般都是需要先获取到数据库中原数据,然后再把新对象的内容进行复制,然后再执行更新操作呢?比如下面的代码(1)而不是直接代码(2)
其中Persion为一个pojo类
参数:currentPerson表示从controller层获取到从页面中传递过来的内容---这个很好理解吧。
Service层中:
public void updatePerson(Person currentPerson){
//获取到需要修改内容在数据库中原始的内容信息,也就是调用sesssion.load(id)这hibernate方法,也可以是get方法
Person person = personDao.loadPerson(currentPerson.getId());
//将传递过来的对象的属性内容进行复制到获取的对象中
BeanUtil.copyProperties(currentPerson , person);
//进行hibernate中的session更新操作
personDao.updatePerson(person);
}
代码(2)内容:
其中Persion为一个pojo类
参数:currentPerson表示从controller层获取到从页面中传递过来的内容---这个很好理解吧。
Service层中:
public void updatePerson(Person currentPerson){
//进行hibernate中的session更新操作
personDao.updatePersoncurrentPerson)
}
解答:在上面的service层的这个更新的方法中(当然也可以是在controller层或者是strus2的方法中,只是调用的形式有变化而已),注意到了是先获取到数据库中对应的主键id的内容,然后再根据修改的内容进行的更新操作的。当然,这个问题并不是一定会的,可以说是一种规范吧,就是能够更安全。原因就在于,在hibernate的工作机制中,对应在同一区域(Hibernate缓存区)和时间是不能够有相同主键内容的数据存在的,也就是说不能有两个相同主键的持久化类存在。更为通俗的讲解就是,如果当前需要更新的实体,刚好的主键id对应着Hibernate缓存区中,已经存在了,那么这样就会报一个different object with the same identitifer的错误,很明显就是说存在了相同id的两个持久化类了,所以,通过先拿到当前修改id的原始内容,然后进行修改属性内容之后,再把改对象放入到更新操作中,就相当于从hibernate缓存区先取出已经存在的,然后修改了,再放回去,这样就肯定保证了只会存在一个唯一了,所以就防止不会出现上述的这个错误了。当然,如果不进行先获取,再保存也可以,只是这样增加了安全性,所以记住,如果进行修改操作,那么就需要这样的步骤才是最安全的。
2:如何解决hibernate中,懒加载load方法出现,no session的错误?
解答:这个问题其实是开发中,很经过会遇到的一个问题。之所以出现这样的问题是在于,session对象当执行了相应的crud操作之后,就会结束生命周期了,而当session接受之后,然后又访问刚获取到的对象的相应的内容,那么因为是load()方法是进行懒加载,当真正进行使用该对象的时候,再会真正的去获取,而此时session对象已经关闭了,所以肯定就会出现上面的问题了。就代码解释就是如下的代码:
其中Persion为一个pojo类
参数:id表示从要进行获取到主键id---这个很好理解吧。
Dao层中:
public void loadOpPerson(Long id){
Person person = this.hibernateTemplate.load(Person.class , id);
person.getName(); //执行到这就会报no session的错误
}
原理上面,我解释过了,所以,来说一下如何解决这个问题,其实很好解决,那就是扩大session的生命周期,这样不就可以么吗?所以就可以采取在web.xml中配置一个
OpenSessionInViewFilter过滤器,具体代码如下:
<filter>
<filter-name>