繁体   English   中英

在 Jboss 服务器 (WildFly 18.x) 中将 Hibernate 从 3 升级到 4

[英]Upgrade Hibernate from 3 to 4 inside Jboss server (WildFly 18.x)

我正在尝试将 hibernate 从 3 升级到 4 并遇到多个问题。 这是我们对 v3 的配置。

  @Bean
  public LocalSessionFactoryBean sessionFactory(DataSource datasource) {
    LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
    sessionFactory.setDataSource(datasource);
    sessionFactory.setPackagesToScan("com.company.hs.service");
    sessionFactory.setHibernateProperties(hibernateProperties());
    return sessionFactory;
  }

  @Bean
  public HibernateTransactionManager transactionManager(SessionFactory sessionFactory) {
    HibernateTransactionManager transactionManager = new HibernateTransactionManager();
    transactionManager.setSessionFactory(sessionFactory);
    return transactionManager;
  }


  private Properties hibernateProperties() {
    Properties properties = new Properties();
    properties.put("hibernate.dialect", "com.company.hs.service.hibernate.MySQL5InnoDBIndexDialect");
    properties.put("hibernate.show_sql", Boolean.TRUE.toString());
    properties.put("hibernate.generate_statistics", Boolean.FALSE.toString());

    properties.put("transaction.factory_class", "org.hibernate.transaction.JTATransactionFactory");
    properties.put("transaction.manager_lookup_class", "org.hibernate.transaction.JBossTransactionManagerLookup");

    properties.put("hibernate.cache.use_query_cache", Boolean.TRUE.toString());
    properties.put("hibernate.cache.use_second_level_cache", Boolean.TRUE.toString());

    return properties;
   }

升级依赖版本和类包本身后,我能够编译和启动应用程序。

但是,在尝试对 DB 执行任何写操作后,我收到以下错误:

org.springframework.dao.InvalidDataAccessApiUsageException: Write operations are not allowed in read-only mode (FlushMode.MANUAL): Turn your Session into FlushMode.COMMIT/AUTO or remove 'readOnly' marker from transaction definition.

在研究了大量信息后,似乎有多种选择。

选项 1 :像如何使用 Spring 4.0.6 为 Hibernate 4.3.5.Final 全局设置 FlushMode 中建议的那样覆盖 OpenSessionInViewFilter

虽然它似乎有帮助,但当应用程序行为改变时有多种边缘情况(即,在使用@GeneratedValue(strategy = GenerationType.IDENTITY) ,HIbernateTemplate 的方法persist不会就地更新实体 ID,因此我们必须使用save方法)。 总的来说,担心其他副作用,因为这里似乎没有适当地参与事务管理。

选项 2 :正如https://crunchtech.io/blog/migrating-from-hibernate-3-to-4-with/ 中所建议的,我们可以切换到CMTTransactionFactory而不是使用JTATransactionFactory 这似乎是我们想要进行的事情,因为我们希望 Spring 容器来管理事务。 对应spring javadocs - https://docs.spring.io/spring-framework/docs/3.2.0.M1_to_3.2.0.M2/changes/docdiffs_org.springframework.orm.hibernate4.html

在尝试执行 SQL 查询时,它因org.hibernate.TransactionException: Could not register synchronization for container transaction失败。

仅供参考,仅此部分更改了原始配置:

    properties.put("hibernate.transaction.factory_class", "org.hibernate.transaction.CMTTransactionFactory");
    properties.put("hibernate.transaction.manager_lookup_class", "org.hibernate.transaction.JBossTransactionManagerLookup");
    properties.put("hibernate.transaction.jta.platform", "org.hibernate.service.jta.platform.internal.JBossAppServerJtaPlatform");

有争议的是,Spring 的错误跟踪器建议采用完全相反的方法 - https://github.com/spring-projects/spring-framework/issues/15230

选项 3将使用 AOP 方面,该方面将围绕@Transactional执行以将数据刷新到数据库中。

选项 4使用 JPA

恕我直言,3 和 4 的可能性非常低。

互联网上的多个示例表明,从 3 -> 4 迁移 Hibernate 应该是 Tomcat 的魅力所在,并且大多数问题都是在 Jboss/GlassFish 服务器中运行时出现的。 不幸的是,我们在 WildFly 中运行我们的应用程序。

在这一点上,我很感激对此的任何意见。 从什么是通用使用范式的问题开始,也许这里提到的选项完全关闭,我们需要使用不同的机制。 或者我们缺少一些关键的配置。

对应的依赖版本

Spring - 4.0.5.RELEASE
Hibernate - 4.2.12.Final
WildFly - 18.0.1

我确实设法让它与在 WildFly 中运行的 Spring 4 Hibernate 5 一起工作,而无需自定义OpenSessionInViewFilter或指定特定于容器的属性(如hibernate.transaction.factory_classhibernate.transaction.manager_lookup_class )。 成功的关键是正确使用@Transactional注释和一点点 tweeking 查询本身。

更要的是,在我的测试应用中启用JTA事务属性(比如规定在这里)引起的副作用,如在运行时异常不正确回滚。 这些是我用来启用它的属性:

properties.put("hibernate.transaction.jta.platform", "JBossAS");
properties.put("hibernate.transaction.coordinator_class", "jta");

没有指定这些的相同代码按预期回滚所有中间数据库条目。 还不知道为什么会这样,但是我们没有充分的理由首先使用 JTA 事务。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM