合格的 bean 必须是 Spring Boot 3 中的“EntityManagerFactory”类型。适用于 Spring Boot 2

taf*_*fli 1 java spring hibernate jpa spring-boot

我目前正在使用自己的JpaTransactionmanager配置将我的项目升级到 Spring Boot 3。

我的代码如下所示:

@Configuration
@EnableJpaRepositories(
    entityManagerFactoryRef = "myEntityManagerFactory",
    transactionManagerRef = "myTransactionManager"
)
public class MyPersistenceConfig {

    ...

    @Bean
    public LocalContainerEntityManagerFactoryBean myEntityManagerFactory(DataSource dataSource) {
        var emfBean = new LocalContainerEntityManagerFactoryBean();

        // Some configuration removed

        return emfBean;
    }

    @Bean
    public JpaTransactionManager myTransactionManager(@Qualifier("myEntityManagerFactory") EntityManagerFactory emf) {
        var transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(emf);
        return transactionManager;
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,此代码适用于最新的 Spring Boot 2,但不适用于 Spring Boot 3。启动时会引发以下(最小化)错误:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myEntityManagerFactory' defined in class path resource [<path>/<to>/MyPersistenceConfig.class]: Unable to resolve name [org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy] as strategy [org.hibernate.boot.model.naming.PhysicalNamingStrategy]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1751) ~[spring-beans-6.0.2.jar:6.0.2]
...
Caused by: org.hibernate.boot.registry.selector.spi.StrategySelectionException: Unable to resolve name [org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy] as strategy [org.hibernate.boot.model.naming.PhysicalNamingStrategy]
...
Caused by: org.hibernate.boot.registry.classloading.spi.ClassLoadingException: Unable to load class [org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy]
    at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl.classForName(ClassLoaderServiceImpl.java:123) ~[hibernate-core-6.1.5.Final.jar:6.1.5.Final]
...
Caused by: java.lang.ClassNotFoundException: Could not load requested class : org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
    at org.hibernate.boot.registry.classloading.internal.AggregatedClassLoader.findClass(AggregatedClassLoader.java:210) ~[hibernate-core-6.1.5.Final.jar:6.1.5.Final]
...
Run Code Online (Sandbox Code Playgroud)

除此之外,IntelliJ 在 JpaTransactionManager-Bean 上说:Could not autowire. Qualified bean must be of 'EntityManagerFactory' type.

根据LocalContainerEntityManagerFactoryBean-JavaDoc ,它应该生成一个-BeanEntityManagerFactory(实际上在 Spring-ORM 5 中也是如此):

FactoryBean that creates a JPA EntityManagerFactory according to JPA's standard container bootstrap contract. 
Run Code Online (Sandbox Code Playgroud)

我有什么遗漏的吗?

Seb*_*ian 6

问题似乎是org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy自 Spring Boot 2.6 以来已被弃用,并在 Spring Boot 3 中被删除,取而代之的是CamelCaseToUnderscoresNamingStrategy. 请参阅此处:https: //docs.spring.io/spring-boot/docs/2.7.1/api/index.html ?org/springframework/boot/orm/jpa/hibernate/SpringPhysicalNamingStrategy.html

  • 非常感谢您的提示。没看到那个弃用!设置休眠命名策略后,它起作用了!`spring.jpa.hibernate.naming.physical-strategy='org.hibernate.boot.model.naming.CamelCaseToUnderscoresNamingStrategy'` (2认同)