为什么我们需要始终在hibernate中启动事务来保存,插入,删除或更新?
默认情况下,自动提交功能在休眠时是否为false?
喜欢这个
public static void main(String[] args) {
System.out.println("creating empopbjects");
emp e1=new emp("a","x",1234);
emp e2=new emp("b","y",324);
emp e3=new emp("c","z",23345);
System.out.println("saving emp objects..");
Session s=myfactory.getsession();
s.save(e1);
s.save(e2);
s.save(e3);
s.close();
System.out.println("successfully saved");
}
这不会保存任何东西,而如果我添加交易,那么只添加它?为什么呢?
public static void main(String[] args) {
System.out.println("creating empopbjects");
emp e1=new emp("a","x",1234);
emp e2=new emp("b","y",324);
emp e3=new emp("c","z",23345);
System.out.println("saving emp objects..");
Session s=myfactory.getsession();
Transaction t =s.beginTransaction();
s.save(e1);
s.save(e2);
s.save(e3);
t.commit();
s.close();
System.out.println("successfully saved");
}
答案 0 :(得分:2)
Hibernate Session是Unit of Work,查询仅在刷新时执行(可能在执行任何查询之前,或者当前正在执行的Transaction已提交时)。
自动提交仅在SQL控制台中有意义,在企业应用程序中不可取。使用ORM工具时,您正在管理实体对象状态转换,而不是执行DML操作。只有在刷新时才会将状态转换转换为DML操作。
因此,虽然您可以在自动提交中编写JDBC语句,但JPA不允许您这样做。
答案 1 :(得分:2)
来自one of the SO page的问题的明确答案就在这里。
查看以下代码,其中 无需访问数据库 交易边界:
Session session = sessionFactory.openSession(); session.get(Item.class, 123l); session.close();
默认情况下,在Java SE环境中 使用JDBC配置,这是 如果执行此操作会发生什么 片段:
- 打开一个新会话。它没有获得数据库连接 点。
- 对get()的调用会触发SQL SELECT。 Session现在获得了JDBC 从连接池连接。 默认情况下,Hibernate立即执行 在此关闭自动提交模式 与setAutoCommit的连接(false)。 这有效地启动了JDBC 交易!
- SELECT在此JDBC事务中执行。会议是 关闭,并返回连接 到游泳池并由Hibernate发布 - Hibernate在JDBC上调用close() 连接。怎么了? 未提交的交易?
醇>这个问题的答案是,“它 取决于!“JDBC规范 对待处理没有说什么 调用close()时的事务 一个连接。会发生什么取决于 供应商如何实施 规格。使用Oracle JDBC 司机,例如,打电话给 close()提交事务!最 其他JDBC供应商采取理智的路线 并回滚任何待处理的交易 当JDBC Connection对象是 关闭,资源返回 游泳池。
显然,这不会是一个问题 你执行的SELECT,但看 在这种变化:
Session session = getSessionFactory().openSession(); Long generatedId = session.save(item); session.close();
此代码导致INSERT 声明,在一个内部执行 从未提交的事务或 回滚。在Oracle上,这篇文章 代码永久插入数据;在 其他数据库,它可能不会。 (这个 情况略多一些 复杂:执行INSERT 只有标识符生成器 需要它。例如,一个 标识符值可以从中获得 没有INSERT的序列。的的 然后将持久实体排队直到 冲洗时间插入 - 永远不会 发生在此代码中。身份 策略需要立即INSERT 要生成的值。)
底线:使用显式事务划分。