首页 > 解决方案 > NoSuchMethodError Table.indexes() hibernate-core-5.2.13.Final.jar 尝试启动应用程序时?

问题描述

有应用srping+jpa。Webserver 是 Websphere 8.5.13 因此,我使用添加配置的 WebApplicationInitializer 启动应用程序。

添加 PersisnteceConfig 时出现问题:

import org.hibernate.jpa.HibernatePersistenceProvider;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.annotation.Resource;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import java.util.Properties;

@Configuration
@EnableTransactionManagement
@EnableJpaAuditing
@EnableJpaRepositories(basePackages = {"persistence"})
@PropertySource("classpath:application.properties")
@ComponentScan(basePackages = {"persistence"})
public class PersistenceConfig {
    private static final String PROP_DATABASE_DRIVER = "db.driver";
    private static final String PROP_DATABASE_URL = "db.url";
    private static final String PROP_DATABASE_USERNAME = "db.username";
    private static final String PROP_DATABASE_PASSWORD = "db.password";
    private static final String PROP_HIBERNATE_DIALECT = "db.hibernate.dialect";
    private static final String PROP_HIBERNATE_SHOW_SQL = "db.hibernate.show_sql";
    private static final String PACKAGE_WITH_JPA_ENTITIES = "ru.sbrf.risks.services.data.persistence";
    private static final String PROP_HIBERNATE_HBM2DDL_AUTO = "db.hibernate.hbm2ddl.auto";
    private static final String DO_NOT_AUDIT_LOCKING_FIELD = "org.hibernate.envers.do_not_audit_optimistic_locking_field";

    @Resource
    private Environment env;

    @Bean
    public DataSource dataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName(env.getRequiredProperty(PROP_DATABASE_DRIVER));
        dataSource.setUrl(env.getRequiredProperty(PROP_DATABASE_URL));
        dataSource.setUsername(env.getRequiredProperty(PROP_DATABASE_USERNAME));
        dataSource.setPassword(env.getRequiredProperty(PROP_DATABASE_PASSWORD));
        return dataSource;
    }

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
        System.out.println("1");
        LocalContainerEntityManagerFactoryBean entityManager = new LocalContainerEntityManagerFactoryBean();
        System.out.println("2");
        entityManager.setDataSource(dataSource());
        System.out.println("3");
        entityManager.setPackagesToScan(PACKAGE_WITH_JPA_ENTITIES);
        System.out.println("4");
        entityManager.setPersistenceProviderClass(HibernatePersistenceProvider.class);
        System.out.println("5");
        entityManager.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
        System.out.println("6");
        entityManager.setJpaProperties(getHibernateProperties());
        System.out.println("7");
        return entityManager;
    }

    @Bean
    public JpaTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(entityManagerFactory);
        return transactionManager;
    }

    //Set properties hibernate
    private Properties getHibernateProperties() {
        Properties properties = new Properties();
        properties.put("hibernate.dialect", env.getRequiredProperty(PROP_HIBERNATE_DIALECT));
        properties.put("hibernate.show_sql", env.getRequiredProperty(PROP_HIBERNATE_SHOW_SQL));
        properties.put("hibernate.hbm2ddl.auto", env.getRequiredProperty(PROP_HIBERNATE_HBM2DDL_AUTO));
        properties.put("org.hibernate.envers.do_not_audit_optimistic_locking_field",
                env.getRequiredProperty(DO_NOT_AUDIT_LOCKING_FIELD));

        properties.put("verifyServerCertificate", false);
        properties.put("useSSL", false);
        properties.put("requireSSL", false);
        properties.put("useLegacyDatetimeCode", false);
        properties.put("useUnicode", "yes");
        properties.put("characterEncoding", "UTF-8");
        properties.put("serverTimezone", "UTC");
        properties.put("useJDBCCompliantTimezoneShift", true);
        return properties;
    }
}

所以,我使用 hibernate-core-5.2.13.Final 库,当尝试在 WebSphere 8.5.13 上启动应用程序时,我收到一条错误消息:

调用 init 方法失败;嵌套异常是 java.lang.NoSuchMethodError: javax/persistence/Table.indexes()[Ljavax/persistence/Index; (从文件:/opt/IBM/WebSphere/AppServer/plugins/javax.j2ee.persistence.jar 由 org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader@ec08ccb6 加载)从类 org.hibernate.cfg.annotations.EntityBinder 调用(从文件:/opt/IBM/WebSphere/AppServer/profiles/AppSrv01/installedApps/MyApp_war.ear/MyApp.war/WEB-INF/lib/hibernate-core-5.2.13.Final.jar 由 com.ibm 加载。 ws.classloader.CompoundClassLoader@7f080f2e[war:MyApp_war/MyApp.war]

标签: springjpawebsphere

解决方案


您正在尝试使用实现与 WebSphere 8.5.5 中包含的 JPA 2.0 不同的规范版本的 Hibernate 版本。可以这样做,但您还需要带上您自己的 JPA API 版本。为此,您需要将 Web 模块的类加载器切换到“Parent Last”,或者将 Hibernate 和 JPA API jar 移动到共享库并将库配置为使用隔离的类加载器(有效地设置“父母最后”仅适用于图书馆中的罐子)。


推荐阅读