gpt4 book ai didi

java - Hibernate - 同一 session 中的第二个事务不保存修改后的对象

转载 作者:行者123 更新时间:2023-12-01 09:50:57 26 4
gpt4 key购买 nike

好的,所以我的问题是我在同一个 session 中执行第二个事务,看来作为第二个事务一部分的任何修改的对象都不会被 session.save() 保存。我比较了第一个事务的运行,并注意到第二个事务期间引用的任何对象都不在持久性上下文中。这是第一笔交易:

197459 [http-nio-8080-exec-1] DEBUG com.microstar.tap2.processors.ShipmentProcessor  - Saving updated shipment!
197476 [http-nio-8080-exec-1] DEBUG org.springframework.orm.hibernate4.HibernateTransactionManager - Initiating transaction commit
197476 [http-nio-8080-exec-1] DEBUG org.springframework.orm.hibernate4.HibernateTransactionManager - Committing Hibernate transaction on Session [SessionImpl(PersistenceContext[entityKeys=[EntityKey[com.microstar.tap2.datamodel.tap.User#23896], EntityKey[com.microstar.tap2.datamodel.tap.Shipment#778901], EntityKey[com.microstar.tap2.datamodel.tap.User#22268], EntityKey[com.microstar.tap2.datamodel.tap.User#19991

第二笔交易显示:

402754 [http-nio-8080-exec-3] DEBUG com.microstar.tap2.processors.ShipmentProcessor  - Saving updated shipment!
402754 [http-nio-8080-exec-3] DEBUG org.springframework.orm.hibernate4.HibernateTransactionManager - Initiating transaction commit
402754 [http-nio-8080-exec-3] DEBUG org.springframework.orm.hibernate4.HibernateTransactionManager - Committing Hibernate transaction on Session [SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[insertions=org.hibernate.engine.spi.ExecutableList@57573be6 updates=org.hibernate.engine.spi.ExecutableList@1255bf68

对于这两个事务,我的代码执行是相同的...我已经单步执行了很多次。它与对同一数据库的同一表中的两个不同行执行的方法完全相同。这是在 AWS Elastic Beanstalk (Tomcat8) 中运行 Java 8 - 但也从 Eclipse/Tomcat8 中在 Java8 上运行。

此应用程序是 REST API。这是资源定义:

@Transactional
@RequestMapping(value = "/{id}/quote", method = RequestMethod.GET)

该方法不直接对 session /hibernate 执行任何操作。但它称 DAO 确实可以。所有资源 Controller 所做的第一件事是检查身份验证/授权:

String tapUserId = authUtil.checkAuthorization(...)

这又调用 DAO,并且所有 DAO 的基类都有一个方法:

Session getSession()
{
if (session == null)
{
try
{
session = sessionFactory.getCurrentSession();
logger.debug("Got current session: " + session);
} catch (Exception ex)
{
logger.debug("NO current session!");
}
}
if (session == null)
{
session = sessionFactory.openSession();
logger.debug("Opened new session: " + session);
}
if ( session != null && !session.isOpen() )
{
session = sessionFactory.openSession();
logger.debug("Had to re-open session: " + session);
}

return session;
}

它接下来要做的就是使用 Hibernate 获取 cargo :

    logger.debug("Using orderId: " + orderId);
session = getSession();
Query query = session.getNamedQuery(Shipment.SHIPMENT_FINDBY_ORDERID_ID);
query.setString("orderid", orderId);
Object r = query.uniqueResult();
if ( r == null )
return null;

return (Shipment)r;

第二个事务的日志显示调试消息“获取当前 session ”,转储 session 显示 PersistenceContext 中的entityKeys 数组为空 - 但我希望此时会出现这种情况。而在第一个事务中,日志条目是“Opened new Session” - 再次使用空的entityKeys数组。

资源 Controller 的最后一个功能行调用 DAO 来更新记录,从而执行以下操作:

    session = getSession();
session.save(shipment);
return shipment;

我完全不明白为什么这甚至是一个问题,但我猜我的 session /事务管理做错了。如上所示,资源全部使用 @Transaction - 无修饰符。

那么,我错过了什么?

谢谢,-Mac

最佳答案

如 Spring 所述documentation ,spring 默认每个事务一个 Hibernate Session

为了使您的设置正常工作,您还需要:

  • 让 spring 注入(inject) SessionFactory实例
  • 一旦离开(或进入新的)事务边界(由 @Transactional 标记),就会检索新的 Hibernate Session通过sessionFactory.getCurrentSession()

缓存SessionFactory和/或Session应用程序代码中的实例阻碍了框架正确管理事务的任务。框架无法知道哪个Session应用程序代码决定使用。因此,框架要求应用程序代码获取框架为检索而准备和存储的 session sessionFactory.getCurrentSession() 。在那Session然后框架执行 session 和事务生命周期管理。

我还找到了这个Stackoverflow question还有这个Hibernate Documentation有帮助。

关于java - Hibernate - 同一 session 中的第二个事务不保存修改后的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37602501/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com