@Transactional 在Spring Boot 3 / Hibernate 6中不会启动事务。

huangapple go评论51阅读模式
英文:

@Transactional not starting transactions with Spring Boot 3 / Hibernate 6

问题

我目前正在迁移至 Spring Boot 3 / Hibernate 6。Hibernate 正确解析所有实体和存储库,连接到数据库等等...

然而,似乎 @Transactional 没能正确启动事务。

小例子:

@Component
public class Test {

  @Autowired
  private EntityManagerFactory entityManager;

  @Transactional
  public void test() {
    Session s = entityManager.unwrap(SessionFactory.class).getCurrentSession();
    s.createQuery("FROM sometable").list();
  }
}

错误:

Caused by: org.hibernate.HibernateException: 调用方法 'createQuery' 在没有活动事务的情况下无效当前状态NOT_ACTIVE
	at org.hibernate.context.internal.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:341)

相关配置:

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages="com.somepackage")
@EntityScan(basePackages="com.somepackage")
public class TransactionConfig {
...
}

在 application.properties 中的 session context 类设置:

...
spring.jpa.properties.hibernate.current_session_context_class=thread
...

如果我移除上述设置中的 session_content_class=thread,我会收到这个错误:

Caused by: org.hibernate.HibernateException: 未配置 CurrentSessionContext

编辑 1:

以下仍导致相同错误 "在没有活动事务的情况下无效":

  @PersistenceUnit
  private EntityManagerFactory entityManager;

编辑 2:

如果我不 unwrap 一个 session,只是调用一个继承自 JpaRepository 的类,它可以工作... 但它会创建一个新的事务并忽略父 @Transaction。

英文:

I am currently migrating to Spring Boot 3 / Hibernate 6.
Hibernate is correctly parsing all the entities and repos, connecting to the database, etc...

However, it seems @Transactional is not starting transactions correctly.

Small example:

@Component
public class Test {

  @Autowired
  private EntityManagerFactory entityManager;

  @Transactional
  public void test() {
    Session s = entityManager.unwrap(SessionFactory.class).getCurrentSession();
    s.createQuery("FROM sometable").list();
  }
}

Error:

Caused by: org.hibernate.HibernateException: Calling method 'createQuery' is not valid without an active transaction (Current status: NOT_ACTIVE)
	at org.hibernate.context.internal.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:341)

Relevant Config:

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages="com.somepackage")
@EntityScan(basePackages="com.somepackage")
public class TransactionConfig {
...
}

session context class in application.properties

...
spring.jpa.properties.hibernate.current_session_context_class=thread
...

If I remove the above setting of session_content_class=thread,
I get this error:

Caused by: org.hibernate.HibernateException: No CurrentSessionContext configured

Edit 1:

The below still results in the same error "is not valid without an active transaction"

  @PersistenceUnit
  private EntityManagerFactory entityManager;

Edit 2:

If I do not unwrap a session and just call a class with extends extends JpaRepository, it works... but it creates a new transaction and ignores the parent @Transaction

答案1

得分: 0

修正如下:

	@PersistenceContext 
	private EntityManager entityManager;

解开为:

    Session s = entityManager.unwrap(Session.class);
英文:

Fix was the following:

	@PersistenceContext 
	private EntityManager entityManager;

and to unwrap:

    Session s = entityManager.unwrap(Session.class);

huangapple
  • 本文由 发表于 2023年2月9日 03:41:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/75390962.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定