当你的session会话去数据库中get一个对象也就代表去数据库里面查了一次,获得到的对象也就是数据库中的数据,当你用get获取的对象状态为持久态,也就是你对这个对象进行删除或者修改的话数据库中对应的数据也会相应的改变
持久状态的对象也会根据不同的操作变成临时状态和游离状态,临时状态的对象当你对它进行操作是不会影响到数据库中的数据,
游离状态的对象也能通过update变成持久状态,而游离状态情况下的对象你对它进行操作,它可能会影响到数据库中的数据,也有可能不会影响
Hibernate对象的加载机制
这个理论相对简单,也就是当你用session.get获取的对象加载机制为立即加载,也就是说当你用了这个方法它就会立马加载这个对象 而你用session.load加载获取到的对象为延迟对象,这个对象只有当你要使用它的时候它才会加载,当你只用load这个方法加载的对象一个代理对象,并不是一个能直接使用的对象
来说说hibernate的并发控制,有这么一种情况,假设两个用户同时去修改同一条数据,两个人取出来的值是一致的,但是两个人需要修改成不同的内容,当a修改的时候成功了,但是b修改的时候将a修改的内容覆盖了,这个时候数据就有问题了,面对这种问题hibernate有对应的解决办法,接下来贴代码
首先在实体类中添加一个属性
private Integer version;
public Integer getVersion() {
return version;
}
public void setVersion(Integer version) {
this.version = version;
}
然后在其对应的xml文件中做以下改动
在class标签中加上
<version name="version" type="java.lang.Integer" column="version"></version>
贴上示例代码 SessionFactoryUtil这个类在之前的博客中有贴代码
public static void edit(student s) {
Session session = SessionFactoryUtil.getSession();
//事务
Transaction transaction = session.beginTransaction();
//修改
session.update(s);
transaction.commit();
session.close();
}
public static void main(String[] args) {
student s = new student();
s.setSid(1);
s.setSname("sss");
// System.out.println(add(s));
s.setVersion(0);
edit(s);
}
main方法模拟的情况就为以上我描述的业务场景,version这个属性能从查询中获得,这种情况下,a和b拿到的version数据是一样但是由于一个先一个后,后面修改的情况就会报Error during managed flush [Row was updated or deleted by another transaction的错,当然数据库中也要有version这个列名才行,这个version相当一个版本号,每做一次修改就会增加,也就保证了数据的准确性