- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我将我正在开发的应用程序从使用 AspectJ 加载时间编织切换到使用 Spring CGlib 代理,并且在我这样做之后,我开始在代码的许多部分中获得 hibernate 延迟加载异常,而在过去有没有抛出异常。
我已经能够通过将 @Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
添加到之前没有任何事务属性的公共(public)方法中来解决这些延迟加载异常但调用 spring 存储库从数据库中读取数据。
任何人都知道为什么添加 @Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
会消除 hibernate 延迟加载异常,以及为什么 AspectJ 加载时间编织不需要这些注释但需要出来了吗?
更新 2我认为删除 AspectJ 不是问题,但问题是我并不真正了解 SUPPORTS 传播的实际行为。特别是 SUPPORTS 如何与 JPA EntityManager 交互,因此我删除了一堆导致延迟加载异常的 SUPPORTS 传播。在阅读了 Spring Transaction Manager 的源代码之后,该做什么就变得很清楚了。 Spring 文档并没有很好地指出的关键思想是 @Transactional 注释用作将 EntityManager 的生命周期与事务方法的开始和结束联系起来的同步点。也强烈推荐http://www.ibm.com/developerworks/java/library/j-ts1/上的这一系列文章和这篇博文 http://doanduyhai.wordpress.com/2011/11/21/spring-persistencecontext-explained/
更新 1
这不是通过 AOP 代理调用私有(private) @Transactional 方法的情况。这些问题发生在从其他服务调用的公共(public)方法中。
这是代码结构的示例,我在其中看到了问题的发生。
@Service
public class FooService
{
@Autowired
private BarService barService;
public void someMethodThatOnlyReads() {
SomeResult result = this.barService.anotherMethodThatOnlyReads()
// the following line blows up with a HibernateLazyLoadingEcxeption
// unless there is a @Transactional supports annotation on this method
result.getEntity().followSomeRelationship();
}
}
@Service
public class BarService
{
@Autowired
private BarRepository barRepo;
public SomeResult anotherMethodThatOnlyReads()
{
SomeEntity entity = this.barRepo.findSomeEntity(1123);
SomeResult result = new SomeResult();
result.setEntity(entity);
return result;
}
}
@Repository
public class BarRepository
{
@PersistenceContext
private EntityManager em;
public SomeEntity findSomeEntity(id Integer)
{
em.find(SomeEntity.class,id);
}
}
最佳答案
我假设您的代码没有使用 OpenSessionInViewFilter
或类似的东西。
没有 @Transactional
注解,Hibernate session 在离开 BarRepository.findSomeEntity()
后关闭方法。
当一个 @Transactional
方法被调用,TransactionalInterceptor
正确绑定(bind)到方法(通过 cglib 代理或您在 Spring 上下文中拥有的任何其他 AOP 配置),然后 Spring 为整个带注释的方法保持打开状态,从而防止任何延迟加载异常。
如果您将日志记录设为 DEBUG
在 org.springframework.transaction
和 org.springframework.orm.hibernate3
(或 hibernate4
如果您使用的是 Hibernate 4)记录器,尤其是 HibernateTransactionManager
类(class)和org.springframework.transaction.support.AbstractPlatformTransactionManager
,您应该确切地看到 Spring 在代码流中的哪些点决定它需要打开和关闭 Hibernate Session。日志还应显示 session 或事务在每个点打开/关闭的原因。
关于java - 为什么 @Transactional(propagation = Propagation.SUPPORTS, readOnly = true) 修复 Hibernate 延迟加载异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16062893/
我们发生了一个生产事件,导致一堆线程陷入僵局,服务器停止工作。为了进行调查,我测试了一些具有不同的Spring事务传播的东西,如果我没有记错的话,如果根本没有现有的事务,那么REQUIRES_NEW传
我有一个简单的 CRUD 项目。我有一个使用 Hibernate 5 和 Spring Boot 的简单 CRUD 项目。当我使用@Transactional(propagation = Propag
这是我的问题: 我正在 Java EE/Spring/Hibernate 应用程序上运行批处理。此批处理调用 method1。这个方法调用一个method2,它可以抛出UserException(一个
有人可以解释为什么第一个单元测试类工作而第二个测试类失败并出现锁定等待超时错误? 第一个类: public class Test1 extends AbstractTransactionalJUnit
如果我有以下代码: @Component public class A{ @Transactional(propagation = Propagation.REQUIRED) public void
在 Spring 文档中,对于 NEVER 传播: Execute non-transactionally, throw an exception if a transactionexists. 我想
根据Spring javadoc @Transactional(propagation = Propagation.SUPPORTS) Support a current transaction, e
我将 jHipster 与 Spring Data JPA 一起使用,并具有以下方法: @Transactional(propagation=Propagation.REQUIRES_NEW) pub
我正在使用 spring 和 hibernate,并使用 spring 事务管理器。我有以下方法,它是从另一个事务性方法调用的。 @Transactional (readOnly = true, pr
现在基本设置都可以了,我开始尝试交易。Struts+Spring+Hibernate注解事务管理器。这是 Action 中的示例代码,将调用一个服务类: userService.addUser
我有这样的代码 @Transactional(propagation = Propagation.NESTED) @TransactionConfiguration(transactionManage
方法与有什么区别 @Transactional(propagation = Propagation.SUPPORTS) 还有一个没有@Transactional的方法? 例如: public clas
当启动新事务时,在使用@Transactional(propagation = Propagation.REQUIRED)启动的当前事务中使用@Transactional(propagation =
方法与 @Transactional(propagation = Propagation.SUPPORTS) 有什么区别vs 没有 @Transactional注释? @Transactional(p
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Throwable.class) public void abc()
每当我尝试 entityManager.flush() 时,我都会收到标题中提到的错误。有趣的是,我的所有模型都在应用程序启动期间在 MySql 上正确创建。 我已经阅读了几个具有类似异常的问题,基本
我正在开发一个 java (spring/hibernate) 应用程序,它是一种限时且数量有限的销售平台。也就是说,我必须在上午 10 点到 11 点的时间段内只销售 1000 张某种类型的卡片。我
@Transactional(rollbackFor = Exception.class) public void foo1() { `/**Some Code**/` } @Transact
我将我正在开发的应用程序从使用 AspectJ 加载时间编织切换到使用 Spring CGlib 代理,并且在我这样做之后,我开始在代码的许多部分中获得 hibernate 延迟加载异常,而在过去有没
我一直在尝试追踪现有 MySQL(5.7,Linux)代码中的错误行为。我对我发现的行为感到震惊/困惑/不高兴当子查询返回错误时: SELECT * FROM charges WHERE Charge
我是一名优秀的程序员,十分优秀!