【问题标题】:How to find compatible version pair of Hibernate + Spring-JPA? (Could not open JPA EntityManager for transaction)如何找到 Hibernate + Spring-JPA 的兼容版本对? (无法为事务打开 JPA EntityManager)
【发布时间】:2017-01-09 14:49:16
【问题描述】:

SSCCE 在这里:https://github.com/dims12/TrySpringJpaPlusHibernate

我正在尝试在没有 persistence.xml 的情况下运行 Spring JPA 并具有以下配置:

@Configuration
@ComponentScan
@ImportResource("classpath:data_source.xml")
@EnableJpaRepositories("org.inthemoon.train.chinese.repositories")
public class BaseConfig {
   @Autowired
   private DataSource dataSource;

   @Bean
   public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
      LocalContainerEntityManagerFactoryBean ans =
         new LocalContainerEntityManagerFactoryBean();
      ans.setDataSource(dataSource);
      ans.setJpaVendorAdapter(jpaVendorAdapter());
      ans.setPackagesToScan("org.inthemoon.train.chinese.data");
      return ans;
   }

   @Bean
   public JpaVendorAdapter jpaVendorAdapter() {
      HibernateJpaVendorAdapter ans = new HibernateJpaVendorAdapter();
      ans.setShowSql(false);
      ans.setGenerateDdl(true);
      ans.setDatabase(Database.H2);
      return ans;
   }

   @Bean
   public PlatformTransactionManager transactionManager(EntityManagerFactory emf) {
      JpaTransactionManager ans = new JpaTransactionManager();
      ans.setEntityManagerFactory(emf);

      return ans;
   }

}

它会导致以下异常

Exception in thread "main" org.springframework.transaction.CannotCreateTransactionException: Could not open JPA EntityManager for transaction; nested exception is java.lang.NoSuchMethodError: org.hibernate.Session.getFlushMode()Lorg/hibernate/FlushMode;
...

附:有什么方法可以从第一次尝试配置IoC

更新

我正在使用以下库:

compile group: 'org.hibernate', name: 'hibernate-core', version: '5.2.5.Final'

compile group: 'org.springframework.data', name: 'spring-data-jpa', version: '1.10.5.RELEASE'

更新 2

我尝试了 8 个不同版本的 hibernate-core 来构建 1.10.5.RELEASE 的 spring-jpa。

5.2.15.2.6 的版本导致了同样的异常

NoSuchMethodError: org.hibernate.Session.getFlushMode()Lorg/hibernate/FlushMode;

版本 5.1.35.0.11 导致

ClassNotFoundException: org.hibernate.ejb.HibernateEntityManagerFactory

唯一导致更复杂问题的版本是5.2.0。这是造成

SchemaManagementException: Attempt to resolve foreign key metadata from JDBC metadata failed to find column mappings for foreign key named [FKLOK22W31RKBMIIC2J96T9LTCN

出现的问题:

1)这是否意味着版本5.2.01.10.5兼容?

2) 如果没有实验,我怎么会知道这一点?

3) 以这种方式猜测版本是否正常?依赖管理工具的目的不就是避免这些事情吗?如果spring-data-jpa:1.10.5 依赖于5.2.0 的休眠,那么为什么不在POM 中描述呢?

更新 3

开箱即用示例:https://github.com/dims12/TrySpringJpaPlusHibernate

它不起作用。

【问题讨论】:

  • JPA 和 Hibernate 的不兼容版本
  • @shazin 如何找到兼容的配对?
  • 根据 spring-data-jpa 的 pom 文件,spring-data-jpa 的 1.10.x 行似乎支持 hibernate 5.2.x:github.com/spring-projects/spring-data-jpa/blob/1.10.x/pom.xml
  • @LucasP 那么为什么它不起作用?
  • 您是否将项目部署在应用服务器中,该服务器可能还提供不同版本的休眠库?还是你有其他版本冲突?你能发布mvn dependency:tree的输出吗?

标签: java spring hibernate spring-data-jpa compatibility


【解决方案1】:

Spring Data JPA v1.10.6 依赖于 Spring v4.2(准确地说是 v4.2.9),而 Spring v4.2 不支持 Hibernate v5.2。添加了对 Hibernate v5.2 的支持 only in Spring v4.3。因此,您必须将 Spring 依赖项升级到 v4.3。


将以下依赖项添加到 Gradle 构建文件应该可以工作:

compile 'org.springframework:spring-beans:4.3.4.RELEASE'
compile 'org.springframework:spring-context:4.3.4.RELEASE'
compile 'org.springframework:spring-context-support:4.3.4.RELEASE'
compile 'org.springframework:spring-core:4.3.4.RELEASE'
compile 'org.springframework:spring-jdbc:4.3.4.RELEASE'
compile 'org.springframework:spring-orm:4.3.4.RELEASE'
compile 'org.springframework:spring-tx:4.3.4.RELEASE'

您修改后的代码available on Github。以gradle test 身份运行 Gradle 测试以验证一切正常。

【讨论】:

    【解决方案2】:

    通常当你有这个异常时,这意味着你应该有 hibernate-entitymanager 到你的 porm。如果您使用的是 maven,您可以通过将其添加到您的 pom 中来做到这一点

    <dependency>
       <groupId>org.hibernate</groupId>
       <artifactId>hibernate-entitymanager</artifactId>
       <version>${hibernate.version}</version>
    </dependency>
    

    我还使用通过 bean 定义我的数据源我没有像你那样使用自动装配注入它我不知道它是否以这种方式工作。我更喜欢这样

     @Bean
        public DataSource dataSource() {
            DriverManagerDataSource dataSource = new DriverManagerDataSource();
            dataSource.setDriverClassName("com.mysql.jdbc.Driver");
            dataSource.setUrl("jdbc:mysql://localhost:3306/gescable");
            dataSource.setUsername("root");
            dataSource.setPassword("root");
            return dataSource;
        }
    

    【讨论】:

    • Autowired 只是因为它来自单独的配置,从技术上讲它是一个 bean。
    【解决方案3】:

    我刚刚在我的项目中测试了这个版本:

    <hibernate.version>5.2.5.Final</hibernate.version>
    <version>1.10.5.RELEASE</version>
    

    它对我有用。

    我的配置文件是这样的:

    @Configuration
    @EnableTransactionManagement
    @EnableJpaRepositories(basePackages = "ge.shemo.repositories")
    @EnableJpaAuditing
    public class PersistenceConfig {
    
    @Autowired
    private Environment env;
    
    @Value("${init-db:false}")
    private String initDatabase;
    
    
    @Bean
    public PlatformTransactionManager transactionManager() {
        EntityManagerFactory factory = entityManagerFactory().getObject();
        return new JpaTransactionManager(factory);
    }
    
    
    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
        LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
    
        HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        vendorAdapter.setGenerateDdl(Boolean.FALSE);
        vendorAdapter.setShowSql(Boolean.FALSE);
    
        factory.setDataSource(dataSource());
        factory.setJpaVendorAdapter(vendorAdapter);
        factory.setPackagesToScan("ge.shemo");
    
        Properties jpaProperties = getHibernateProperties();
        factory.setJpaProperties(jpaProperties);
    
        factory.afterPropertiesSet();
        factory.setLoadTimeWeaver(new InstrumentationLoadTimeWeaver());
        return factory;
    }
    
    private Properties getHibernateProperties() {
        Properties prop = new Properties();
        /*prop.put("hibernate.format_sql", "true");*/
        /*prop.put("hibernate.hbm2ddl.auto", "update");*/
        //prop.put("hibernate.hbm2ddl.auto", "validate");
        // prop.put("hibernate.hbm2ddl.import_files","sql/import.sql");
        /*prop.put("hibernate.ejb.entitymanager_factory_name", "irakli");*/
    
        //prop.put("hibernate.show_sql", "true");
        prop.put("hibernate.dialect", "ge.shemo.config.SQLServerUnicodeDialect");
        return prop;
    }
    
    
    @Bean
    public HibernateExceptionTranslator hibernateExceptionTranslator() {
        return new HibernateExceptionTranslator();
    }
    
    
    @Bean
    public DataSource dataSource() {
        BasicDataSource ds = new BasicDataSource();
        ds.setDriverClassName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
    
        ds.setUrl("jdbc:sqlserver://LinkToDB:1433;useUnicode=true;characterEncoding=UTF-8;DatabaseName=Your_DB");
        ds.setUsername("USER");
        ds.setPassword("PASS");
        return ds;
    }
    
    
    
    
    @Bean
    public DataSourceInitializer dataSourceInitializer(DataSource dataSource) {
    
        DataSourceInitializer dataSourceInitializer = new     DataSourceInitializer();
        dataSourceInitializer.setDataSource(dataSource);
        ResourceDatabasePopulator databasePopulator = new ResourceDatabasePopulator();
        //databasePopulator.addScript(new ClassPathResource("db.sql"));
        dataSourceInitializer.setDatabasePopulator(databasePopulator);
        dataSourceInitializer.setEnabled(Boolean.parseBoolean(initDatabase));
        return dataSourceInitializer;
    }
    
    
    @Bean
    public AuditorAware<Long> createAuditorProvider() {
        return new SecurityAuditor();
    }
    
    @Bean
    public AuditingEntityListener createAuditingListener() {
        return new AuditingEntityListener();
    }
    
    
    
    }
    

    【讨论】:

    • 您是否尝试过对数据库执行任何操作?
    • 我将版本更改为我当前的项目 - 第一步是授权 - 然后列出客户端,客户端活动......它正在正确执行一切 - 从数据库获取数据并将更新写回 SQL 服务器。
    • 我在您的示例中没有看到任何数据库操作代码。看我的例子:github.com/dims12/TrySpringJpaPlusHibernate
    • 我现在就试试。乍一看唯一的区别是我用maven你用grandle。我正在下载 Grandle,现在将尝试您的代码
    【解决方案4】:

    好的,问题是Spring Data JPAHibernate 之间的兼容性问题。 @Spring 和 forks @Hibernate 之间似乎缺乏同步解释或 @least 版本兼容性解释。对我来说,我已经设法使它适用于以下版本

    Spring Data JPA and Spring v5.0.0
    1.10.0.RELEASE
    
    and Hibernate 5.4.12.Final
    

    有时当您忘记设置setPackagesToScan() property 以及要在LocalContainerEntityManagerFactorybean 中扫描所需的包时会出现问题,但情况并非如此。所以是的,请查看您的 Spring DataHibernate 版本!干杯

    【讨论】:

      【解决方案5】:

      您是否需要包含休眠功能?据我所知,Spring data-jpa 包含所有必要的休眠组件,所以我不确定为什么需要添加任何额外的休眠依赖项

      【讨论】:

      • 没有 Hibernate 我没有任何 javax.persistence 类。
      • Spring Data JPA 不是 JPA 提供者。它是一个库/框架,在 JPA 提供者(如 Hibernate)之上添加了一个额外的抽象层。所以你还需要一个 JPA 实现。参考:Dzone.
      猜你喜欢
      • 2017-07-25
      • 2023-03-26
      • 2019-10-12
      • 2017-09-08
      • 2019-09-08
      • 2014-06-17
      • 2018-03-21
      • 2020-05-27
      • 2016-08-06
      相关资源
      最近更新 更多