带有 Spring Boot 和 websphere 8.5.0.1 的 JPA 2.1

Posted

技术标签:

【中文标题】带有 Spring Boot 和 websphere 8.5.0.1 的 JPA 2.1【英文标题】:JPA 2.1 with Spring boot and websphere 8.5.0.1 【发布时间】:2015-11-24 18:41:39 【问题描述】:

我知道这可能是一个重复的问题,但即使在这里和那里引用了几篇文章,我也无法让它发挥作用。我正在尝试在使用 spring boot 最新版本的 websphere 中部署一个简单的应用程序。由于 spring boot 使用的是 JPA 2.1 hibernate jars,它们与 websphere 8.5.0.1 附带的 JPA 2.0 jars 发生冲突。为了完成这项工作,我必须从我的 spring boot 数据 maven 条目中排除 hibernate jar,并指定一个较低版本的 hibernate。虽然这已经奏效,但我并不满意,因为我无法使用最新的休眠实现。所以试图将hibernate最新(JPA 2.1)作为websphere中的第三方提供者。 这是我到目前为止所尝试的: 1. Environment -> Shared Library -> Created a new SharedLibrary -> 将classpath作为你的c:/app/lib 2. WebApplication Server -> my Server -> Java and Process Management -> Class Loader -> New - 首先使用应用程序类加载器加载的类 -> 添加上一步创建的共享库。

在 Server -> Class Loader 是 Single 并且 Parent 最终被选中。 尝试启动应用程序时出现以下异常:

Caused by: java.lang.LinkageError: loading constraint violation: loader "com/ibm/ws/classloader/CompoundClassLoader@da74f152" previously initiated loading for a different type with name "org/xml/sax/Locator" defined by loader "com/ibm/oti/vm/BootstrapClassLoader@53942f80"
[11/24/15 9:26:14:812 EST] 00000056 SystemErr     R     at java.lang.ClassLoader.defineClassImpl(Native Method)
[11/24/15 9:26:14:812 EST] 00000056 SystemErr     R     at java.lang.ClassLoader.defineClass(ClassLoader.java:286)
[11/24/15 9:26:14:812 EST] 00000056 SystemErr     R     at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:154)
[11/24/15 9:26:14:812 EST] 00000056 SystemErr     R     at com.ibm.ws.classloader.CompoundClassLoader._defineClass(CompoundClassLoader.java:853)
[11/24/15 9:26:14:812 EST] 00000056 SystemErr     R     at com.ibm.ws.classloader.CompoundClassLoader.localFindClass(CompoundClassLoader.java:763)
[11/24/15 9:26:14:812 EST] 00000056 SystemErr     R     at com.ibm.ws.classloader.CompoundClassLoader.loadClass(CompoundClassLoader.java:604)
[11/24/15 9:26:14:812 EST] 00000056 SystemErr     R     at java.lang.ClassLoader.loadClass(ClassLoader.java:660)
[11/24/15 9:26:14:812 EST] 00000056 SystemErr     R     at java.lang.J9VMInternals.verifyImpl(Native Method)
[11/24/15 9:26:14:812 EST] 00000056 SystemErr     R     at java.lang.J9VMInternals.verify(J9VMInternals.java:85)
[11/24/15 9:26:14:812 EST] 00000056 SystemErr     R     at java.lang.J9VMInternals.verify(J9VMInternals.java:83)
[11/24/15 9:26:14:812 EST] 00000056 SystemErr     R     at java.lang.J9VMInternals.initialize(J9VMInternals.java:162)
[11/24/15 9:26:14:812 EST] 00000056 SystemErr     R     at ch.qos.logback.core.joran.event.SaxEventRecorder.startElement(SaxEventRecorder.java:109)
[11/24/15 9:26:14:812 EST] 00000056 SystemErr     R     at org.apache.xerces.parsers.AbstractSAXParser.startElement(Unknown Source)
[11/24/15 9:26:14:813 EST] 00000056 SystemErr     R     at org.apache.xerces.impl.XMLNSDocumentScannerImpl.scanStartElement(Unknown Source)
[11/24/15 9:26:14:813 EST] 00000056 SystemErr     R     at org.apache.xerces.impl.XMLNSDocumentScannerImpl$NSContentDispatcher.scanRootElementHook(Unknown Source)
[11/24/15 9:26:14:813 EST] 00000056 SystemErr     R     at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
[11/24/15 9:26:14:813 EST] 00000056 SystemErr     R     at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
[11/24/15 9:26:14:813 EST] 00000056 SystemErr     R     at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
[11/24/15 9:26:14:813 EST] 00000056 SystemErr     R     at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
[11/24/15 9:26:14:813 EST] 00000056 SystemErr     R     at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
[11/24/15 9:26:14:813 EST] 00000056 SystemErr     R     at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
[11/24/15 9:26:14:813 EST] 00000056 SystemErr     R     at org.apache.xerces.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
[11/24/15 9:26:14:813 EST] 00000056 SystemErr     R     at org.apache.xerces.jaxp.SAXParserImpl.parse(Unknown Source)
[11/24/15 9:26:14:813 EST] 00000056 SystemErr     R     at ch.qos.logback.core.joran.event.SaxEventRecorder.recordEvents(SaxEventRecorder.java:61)
[11/24/15 9:26:14:814 EST] 00000056 SystemErr     R     at ch.qos.logback.core.joran.GenericConfigurator.doConfigure(GenericConfigurator.java:134)
[11/24/15 9:26:14:814 EST] 00000056 SystemErr     R     at ch.qos.logback.core.joran.GenericConfigurator.doConfigure(GenericConfigurator.java:99)
[11/24/15 9:26:14:814 EST] 00000056 SystemErr     R     at ch.qos.logback.core.joran.GenericConfigurator.doConfigure(GenericConfigurator.java:49)
[11/24/15 9:26:14:814 EST] 00000056 SystemErr     R     at ch.qos.logback.classic.util.ContextInitializer.configureByResource(ContextInitializer.java:77)
[11/24/15 9:26:14:814 EST] 00000056 SystemErr     R     at org.springframework.boot.logging.logback.LogbackLoggingSystem.loadConfiguration(LogbackLoggingSystem.java:119)
[11/24/15 9:26:14:814 EST] 00000056 SystemErr     R     at org.springframework.boot.logging.AbstractLoggingSystem.initialize(AbstractLoggingSystem.java:57)
[11/24/15 9:26:14:814 EST] 00000056 SystemErr     R     at org.springframework.boot.logging.logback.LogbackLoggingSystem.initialize(LogbackLoggingSystem.java:98)
[11/24/15 9:26:14:814 EST] 00000056 SystemErr     R     at org.springframework.boot.logging.LoggingApplicationListener.initializeSystem(LoggingApplicationListener.java:217)
[11/24/15 9:26:14:814 EST] 00000056 SystemErr     R     at org.springframework.boot.logging.LoggingApplicationListener.initialize(LoggingApplicationListener.java:185)
[11/24/15 9:26:14:814 EST] 00000056 SystemErr     R     at org.springframework.boot.logging.LoggingApplicationListener.onApplicationEnvironmentPreparedEvent(LoggingApplicationListener.java:164)
[11/24/15 9:26:14:814 EST] 00000056 SystemErr     R     at org.springframework.boot.logging.LoggingApplicationListener.onApplicationEvent(LoggingApplicationListener.java:144)
[11/24/15 9:26:14:815 EST] 00000056 SystemErr     R     at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:151)
[11/24/15 9:26:14:815 EST] 00000056 SystemErr     R     at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:128)
[11/24/15 9:26:14:815 EST] 00000056 SystemErr     R     at org.springframework.boot.context.event.EventPublishingRunListener.publishEvent(EventPublishingRunListener.java:100)
[11/24/15 9:26:14:815 EST] 00000056 SystemErr     R     at org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared(EventPublishingRunListener.java:59)
[11/24/15 9:26:14:815 EST] 00000056 SystemErr     R     at org.springframework.boot.SpringApplication.run(SpringApplication.java:286)
[11/24/15 9:26:14:815 EST] 00000056 SystemErr     R     at org.springframework.boot.context.web.SpringBootServletInitializer.run(SpringBootServletInitializer.java:134)
[11/24/15 9:26:14:815 EST] 00000056 SystemErr     R     at org.springframework.boot.context.web.SpringBootServletInitializer.createRootApplicationContext(SpringBootServletInitializer.java:125)
[11/24/15 9:26:14:815 EST] 00000056 SystemErr     R     at org.springframework.boot.context.web.SpringBootServletInitializer.onStartup(SpringBootServletInitializer.java:81)
[11/24/15 9:26:14:815 EST] 00000056 SystemErr     R     at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:175)
[11/24/15 9:26:14:815 EST] 00000056 SystemErr     R     at com.ibm.ws.webcontainer.webapp.WebAppImpl.initializeServletContainerInitializers(WebAppImpl.java:613)
[11/24/15 9:26:14:815 EST] 00000056 SystemErr     R     at com.ibm.ws.webcontainer.webapp.WebAppImpl.initialize(WebAppImpl.java:409)
[11/24/15 9:26:14:815 EST] 00000056 SystemErr     R     at com.ibm.ws.webcontainer.webapp.WebGroupImpl.addWebApplication(WebGroupImpl.java:88)
[11/24/15 9:26:14:815 EST] 00000056 SystemErr     R     at com.ibm.ws.webcontainer.VirtualHostImpl.addWebApplication(VirtualHostImpl.java:169)
[11/24/15 9:26:14:816 EST] 00000056 SystemErr     R     ... 96 more

我也尝试过使用默认的 JPA 实现者设置,并尝试将“org.hibernate.jpa.HibernatePersistenceProvider”作为提供者。然后我什至尝试将persistence.xml放入META-INF中,提供者为“org.hibernate.jpa.HibernatePersistenceProvider”。但到目前为止没有任何效果。

当我将类加载选项更改为应用程序的 parent_last 时,我上面提到的异常出现了。如果选择 parent first,则会抛出以下异常:

java.lang.NullPointerException
[11/24/15 9:24:12:794 EST] 00000055 SystemErr     R     at com.ibm.ws.webcontainer.metadata.WebCollaboratorComponentMetaDataImpl.getJ2EEName(WebCollaboratorComponentMetaDataImpl.java:63)

请让我知道我正在尝试的是否可行。如果是,任何人都可以指导我详细的步骤吗?

更新: 以下是我对 JPA 的配置

@Configuration
@EnableTransactionManagement
@PropertySource(value =  ApplicationConstant.DATABASE_PROPERTIES )
public class HibernateConfiguration 

    /**
     *The variable to store the Environment instance variable
     */
    @Autowired
    private Environment environment;

    /**
     * Bean definition to configure Hibernate SessionFactory
     * @return LocalSessionFactoryBean
     */
   /* @Bean
    public LocalSessionFactoryBean sessionFactory() 
        final LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();

        sessionFactory.setDataSource(dataSource());
        sessionFactory.setPackagesToScan(new String[]  ApplicationConstant.PACKAGE_TO_SCAN );
        sessionFactory.setHibernateProperties(hibernateProperties());
        return sessionFactory;
     */

    /**
     * Bean definition to configure datasource for Hibernate SessionFactory
     * @return DataSource
     */
    @Bean
    public DataSource dataSource() 
        JndiObjectFactoryBean jndiObjectFactoryBean = new JndiObjectFactoryBean();
        jndiObjectFactoryBean.setJndiName("jdbc/prsds");
        JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
        DataSource dataSource = dataSourceLookup.getDataSource("jdbc/prsds");
        return dataSource;

        /*
        final DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName(environment.getRequiredProperty(ApplicationConstant.JDBC_DRIVER_CLASSNAME));
        dataSource.setUrl(environment.getRequiredProperty(ApplicationConstant.JDBC_URL));
        dataSource.setUsername(environment.getRequiredProperty(ApplicationConstant.JDBC_USERNAME));
        dataSource.setPassword(environment.getRequiredProperty(ApplicationConstant.JDBC_PASSWORD));
        return dataSource;*/
    

    /**
     * This method is used to set the properties for Hibernate configuration
     * @return Properties
     */
    private Properties hibernateProperties() 
        final Properties properties = new Properties();
        properties.put(ApplicationConstant.HIBERNATE_DIALECT, environment.getRequiredProperty(ApplicationConstant.HIBERNATE_DIALECT));
        properties.put(ApplicationConstant.HIBERNATE_SHOW_SQL, environment.getRequiredProperty(ApplicationConstant.HIBERNATE_SHOW_SQL));
        properties.put(ApplicationConstant.HIBERNATE_FORMAT_SQL, environment.getRequiredProperty(ApplicationConstant.HIBERNATE_FORMAT_SQL));
        return properties;
    

    /**
     * Bean definition to configure Hibernate Transaction manager
     * @param SessionFactory sessionFactory
     * @return
     */
    /*@Bean
    @Autowired
    public HibernateTransactionManager transactionManager(final SessionFactory sessionFactory) 
       final HibernateTransactionManager txManager = new HibernateTransactionManager();
       txManager.setSessionFactory(sessionFactory);
       return txManager;
    */
//  ///////////////////////////////////////////////////

     @Bean
       public LocalContainerEntityManagerFactoryBean entityManagerFactory() 
          LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
          em.setDataSource(dataSource());
          em.setPackagesToScan(new String[]  ApplicationConstant.PACKAGE_TO_SCAN);
         // em.setPersistenceUnitName("txManager");
          JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
          em.setJpaVendorAdapter(vendorAdapter);
          em.setJpaProperties(hibernateProperties());

          return em;
       


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

          return transactionManager;
       

       @Bean
       public PersistenceExceptionTranslationPostProcessor exceptionTranslation()
          return new PersistenceExceptionTranslationPostProcessor();
       

    

POM.XML

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.2.7.RELEASE</version>
    </parent>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>jaxb2-maven-plugin</artifactId>
                <version>1.6</version>
                <executions>
                    <execution>
                        <id>xjc</id>
                        <goals>
                            <goal>xjc</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <schemaDirectory>$project.basedir/src/main/resources/Service_Defination/XSD</schemaDirectory>
                    <outputDirectory>$project.basedir/src/main/java</outputDirectory>
                    <clearOutputDir>false</clearOutputDir>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-ws</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.apache.ws.xmlschema</groupId>
            <artifactId>xmlschema-core</artifactId>
            <version>2.0.1</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
                <artifactId>javax.servlet-api</artifactId>
                <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.hibernate</groupId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>$hibernate.version</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>$hibernate.version</version>
        </dependency>
        <dependency>
            <groupId>com.oracle</groupId>
            <artifactId>ojdbc14</artifactId>
            <version>10.2.0.4.0</version>
        </dependency>
    </dependencies>
</project>

我也尝试过使用和不使用persistence.xml,但这也没有帮助。 这是我尝试过的配置:

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence 
            http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
             version="2.0">
   <persistence-unit name="txManager">
   <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
  <properties>
   <property name="hibernate.transaction.factory_class" value="org.hibernate.transaction.CMTTransactionFactory"></property>
     <property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.WebSphereExtendedJTATransactionLookup"></property>
   </properties>
   </persistence-unit>
</persistence>

请指导我哪里出错了。

【问题讨论】:

【参考方案1】:

您不能将容器管理的 JPA-2.1 与经典的 WebSphere 8.5.x 一起使用。因为它只支持2.0。它已经在各种帖子中讨论过,例如here。如果您确实必须使用 JPA 2.1,您可以使用支持该功能的 WebSphere Liberty,也可以使用应用程序管理的 JPA 并自己创建实体管理器,而不是通过注入。

更新

我不知道在spring-boot怎么做,但是你应该使用下面的代码来初始化EntityManager:

EntityManagerFactory emf =
Persistence.createEntityManagerFactory("persistenceUnitName");
EntityManager em = emf.createEntityManager();

【讨论】:

我明白,正如你所建议的,我试图自己创建实体管理器。请在我包含示例代码的问题中查看我的更新。请让我知道我做错了什么。【参考方案2】:

我能够通过使用自定义 PersistenceProviderResolver 来使用 JPA 2.1 和 Hibernate 4.3.11,这样 Websphere 类就不会干扰 Hibernate https://gist.github.com/jeffsheets/aec3e94870ef903ce7efe33e00563d3c

我根据这里找到的帖子 https://hibernate.atlassian.net/browse/JPA-4

【讨论】:

以上是关于带有 Spring Boot 和 websphere 8.5.0.1 的 JPA 2.1的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot中异步线程池@Async详解

带有 spring-boot 和 spring-security 的 JWT

带有 FeignClient 的 Spring Boot RepositoryRestResource

带有tomcat和cxf-servlet的spring-boot

带有 spring-boot 和 angularjs 的 CORS 不起作用

带有 Spring Boot REST 控制器和 JSON 的空字段