我一直無法讓Spring爲使用Spring Data JPA,Hibernate和log4j的項目注入entityManagerFactory。看起來我們能夠在Spring首次從上下文開始加載Bean時從休眠狀態接收日誌消息。當它試圖加載entityManagerFactory bean時,hibernate無法加載org.apache.logging.log4j.core.appender.db.jpa.converter.ContextMapJsonAttributeConverter。在簽入罐子後,班級實際上在正確的路徑上。我正在使用自定義的appender,但直到現在,我們這並沒有造成任何問題。任何幫助(甚至在正確的方向點),將不勝感激。Spring Data JPA + Hibernate + Log4j2創建entityManagerFactory時發生ClassLoadingException Bean
編輯:我使用log4j的,不只是的log4j,並從Eclipse中運行時,不會出現這個問題。
的context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa-1.0.xsd">
<!-- Directory to scan for repository classes -->
<jpa:repositories base-package="man.prototype.mid.sen" />
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName">
<value>org.postgresql.Driver</value>
</property>
<property name="url">
<value>jdbc:postgresql://localhost:5432/postgres</value>
</property>
<property name="username">
<value>user</value>
</property>
<property name="password">
<value>password</value>
</property>
</bean>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="persistenceUnitName" value="jpaData" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.format_sql">false</prop>
<prop key="hibernate.hbm2ddl.auto">create</prop>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
</beans>
最近我切換到使用log4j的,而不是一個內部的記錄應用程序,並有機會,這是問題的根源。下面是pom.xml中的其他相關性:
<properties>
<!-- Specify the Version for JUnit. -->
<junit.version>4.12</junit.version>
<!-- Specify the Version for each of the packages we use. -->
<apache.activemq.version>5.3.1</apache.activemq.version>
<apache.commons.lang.version>3.4</apache.commons.lang.version>
<apache.commons.collections.version>4.1</apache.commons.collections.version>
<google.guava.version>19.0</google.guava.version>
<apache.httpcomponents.version>4.5.1</apache.httpcomponents.version>
<postgresql.version>9.4-1206-jdbc42</postgresql.version>
<springframework.jms.version>4.2.5.RELEASE</springframework.jms.version>
<springframework.boot.version>1.3.3.RELEASE</springframework.boot.version>
</properties>
<dependencies>
<dependency>
<groupId>org.ini4j</groupId>
<artifactId>ini4j</artifactId>
<version>0.5.2</version>
</dependency>
<!-- Apache -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${apache.commons.lang.version}</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>${apache.httpcomponents.version}</version>
</dependency>
<!-- Routes logs from slf4j to log4j -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.5</version>
</dependency>
<!-- Google -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${google.guava.version}</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.5</version>
</dependency>
<!-- Spring Dependencies -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.2.4.RELEASE</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.9.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
<version>${springframework.jms.version}</version>
</dependency>
<!-- Database -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>5.1.0.Final</version>
</dependency>
<!-- Added to backport LocalDateTime (new to Java 8) to dependencies that won't recognize it -->
<dependency>
<groupId>org.threeten</groupId>
<artifactId>threetenbp</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>${postgresql.version}</version>
</dependency>
<!-- Test Dependencies -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<!-- This is here for JSON dependencies for hibernate/log4j -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.7.2</version>
</dependency>
<!-- Test Dependencies -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>2.0.43-beta</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.19</version>
<scope>runtime</scope>
</dependency>
<!-- Provide slf4j facade for commons logging (which we excluded in the previous dependency) -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.7.19</version>
<scope>runtime</scope>
</dependency>
</dependencies>
<!-- Build settings -->
<build>
<plugins>
<!-- mvn package sonar:sonar -->
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.6.201602180812</version>
<configuration>
<destFile>${sonar.jacoco.reportPath}</destFile>
<append>true</append>
</configuration>
<executions>
<execution>
<id>pre-unit-test</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>manatee.prototype.middleware.sensor.core.SensorMain</mainClass>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.handlers</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.schemas</resource>
</transformer>
<!-- This transformer is here to concatenate log4j2 cache during fatjar creation -->
<transformer
implementation="com.github.edwgiz.mavenShadePlugin.log4j2CacheTransformer.PluginsCacheFileTransformer">
</transformer>
</transformers>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>com.github.edwgiz</groupId>
<artifactId>maven-shade-plugin.log4j2-cachefile-transformer</artifactId>
<version>2.1</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
這是我在運行時出現錯誤:
LogMessage: id=tbd, eventTimestamp=2016-03-29T10:25:14.054, logTimestamp=tbd, reporter=[org.hibernate.Version], level=INFO, text=[HHH000412: Hibernate Core {5.1.0.Final}]
LogMessage: id=tbd, eventTimestamp=2016-03-29T10:25:14.055, logTimestamp=tbd, reporter=[org.hibernate.cfg.Environment], level=INFO, text=[HHH000206: hibernate.properties not found]
LogMessage: id=tbd, eventTimestamp=2016-03-29T10:25:14.055, logTimestamp=tbd, reporter=[org.hibernate.cfg.Environment], level=INFO, text=[HHH000021: Bytecode provider name : javassist]
LogMessage: id=tbd, eventTimestamp=2016-03-29T10:25:14.062, logTimestamp=tbd, reporter=[org.hibernate.service.spi.ServiceBinding], level=DEBUG, text=[Overriding existing service binding [org.hibernate.secure.spi.JaccService]]
LogMessage: id=tbd, eventTimestamp=2016-03-29T10:25:14.073, logTimestamp=tbd, reporter=[org.hibernate.service.internal.AbstractServiceRegistryImpl], level=TRACE, text=[Initializing service [role=org.hibernate.engine.config.spi.ConfigurationService]]
LogMessage: id=tbd, eventTimestamp=2016-03-29T10:25:14.076, logTimestamp=tbd, reporter=[org.hibernate.service.internal.AbstractServiceRegistryImpl], level=TRACE, text=[Initializing service [role=org.hibernate.cache.spi.RegionFactory]]
LogMessage: id=tbd, eventTimestamp=2016-03-29T10:25:14.076, logTimestamp=tbd, reporter=[org.hibernate.cache.internal.RegionFactoryInitiator], level=DEBUG, text=[Cache region factory : org.hibernate.cache.internal.NoCachingRegionFactory]
LogMessage: id=tbd, eventTimestamp=2016-03-29T10:25:14.081, logTimestamp=tbd, reporter=[org.hibernate.annotations.common.Version], level=INFO, text=[HCANN000001: Hibernate Commons Annotations {5.0.1.Final}]
LogMessage: id=tbd, eventTimestamp=2016-03-29T10:25:14.084, logTimestamp=tbd, reporter=[org.hibernate.service.internal.AbstractServiceRegistryImpl], level=TRACE, text=[Initializing service [role=org.hibernate.boot.cfgxml.spi.CfgXmlAccessService]]
LogMessage: id=tbd, eventTimestamp=2016-03-29T10:25:15.229, logTimestamp=tbd, reporter=[org.springframework.beans.factory.support.DefaultListableBeanFactory], level=DEBUG, text=[Retrieved dependent beans for bean 'org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter#3c3d9b6b': [entityManagerFactory]]
LogMessage: id=tbd, eventTimestamp=2016-03-29T10:25:15.232, logTimestamp=tbd, reporter=[org.springframework.context.support.FileSystemXmlApplicationContext], level=WARN, text=[Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in file [c:\git\sen\src\main\resources\context.xml]: Invocation of init method failed; nested exception is org.hibernate.boot.registry.classloading.spi.ClassLoadingException: Unable to load class [org.apache.logging.log4j.core.appender.db.jpa.converter.ContextMapJsonAttributeConverter]]
LogMessage: id=tbd, eventTimestamp=2016-03-29T10:25:15.232, logTimestamp=tbd, reporter=[org.springframework.beans.factory.support.DefaultListableBeanFactory], level=DEBUG, text=[Destroying singletons in org.s[email protected]29647f75: defining beans [sysConfig,org.springframework.data.jpa.repository.config.JpaRepositoryConfigExtension#0,org.springframework.data.repository.core.support.RepositoryInterfaceAwareBeanPostProcessor,emBeanDefinitionRegistrarPostProcessor,jpaMappingContext,org.springframework.context.annotation.internalPersistenceAnnotationProcessor,jpaContext,dataSource,entityManagerFactory,transactionManager,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.event.internalEventListenerProcessor,org.springframework.context.event.internalEventListenerFactory,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor,org.springframework.context.annotation.ConfigurationClassPostProcessor.enhancedConfigurationProcessor,org.springframework.orm.jpa.SharedEntityManagerCreator#0]; root of factory hierarchy]
Beans Exception in reading Spring context. See Stack Trace below:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in file [c:\git\sen\src\main\resources\context.xml]: Invocation of init method failed; nested exception is org.hibernate.boot.registry.classloading.spi.ClassLoadingException: Unable to load class [org.apache.logging.log4j.core.appender.db.jpa.converter.ContextMapJsonAttributeConverter]
編輯2:下面是該項目的依賴關係樹。
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ sen ---
[INFO] man.prototype.mid:sen:jar:0.0.1-SNAPSHOT
[INFO] +- man.prototype.com:logger:jar:0.0.1-SNAPSHOT:compile
[INFO] | \- org.apache.logging.log4j:log4j-api:jar:2.5:compile
[INFO] +- man.prototype.com:messaging:jar:0.0.1-SNAPSHOT:compile
[INFO] | \- javax.websocket:javax.websocket-api:jar:1.1:compile
[INFO] +- org.ini4j:ini4j:jar:0.5.2:compile
[INFO] +- org.apache.commons:commons-lang3:jar:3.4:compile
[INFO] +- org.apache.httpcomponents:httpclient:jar:4.5.1:compile
[INFO] | +- org.apache.httpcomponents:httpcore:jar:4.4.3:compile
[INFO] | +- commons-logging:commons-logging:jar:1.2:compile
[INFO] | \- commons-codec:commons-codec:jar:1.9:compile
[INFO] +- org.apache.logging.log4j:log4j-core:jar:2.5:compile
[INFO] +- org.apache.logging.log4j:log4j-slf4j-impl:jar:2.5:compile
[INFO] +- com.google.guava:guava:jar:19.0:compile
[INFO] +- com.google.code.gson:gson:jar:2.5:compile
[INFO] +- org.springframework:spring-core:jar:4.2.4.RELEASE:compile
[INFO] +- org.springframework:spring-context:jar:4.2.4.RELEASE:compile
[INFO] | +- org.springframework:spring-aop:jar:4.2.4.RELEASE:compile
[INFO] | | \- aopalliance:aopalliance:jar:1.0:compile
[INFO] | +- org.springframework:spring-beans:jar:4.2.4.RELEASE:compile
[INFO] | \- org.springframework:spring-expression:jar:4.2.4.RELEASE:compile
[INFO] +- org.springframework.data:spring-data-jpa:jar:1.9.2.RELEASE:compile
[INFO] | +- org.springframework.data:spring-data-commons:jar:1.11.2.RELEASE:compile
[INFO] | +- org.springframework:spring-orm:jar:4.1.9.RELEASE:compile
[INFO] | | \- org.springframework:spring-jdbc:jar:4.1.9.RELEASE:compile
[INFO] | +- org.springframework:spring-tx:jar:4.1.9.RELEASE:compile
[INFO] | \- org.aspectj:aspectjrt:jar:1.8.7:compile
[INFO] +- org.springframework:spring-jms:jar:4.2.5.RELEASE:compile
[INFO] | \- org.springframework:spring-messaging:jar:4.2.5.RELEASE:compile
[INFO] +- org.hibernate:hibernate-entitymanager:jar:5.1.0.Final:compile
[INFO] | +- org.jboss.logging:jboss-logging:jar:3.3.0.Final:compile
[INFO] | +- org.hibernate:hibernate-core:jar:5.1.0.Final:compile
[INFO] | | +- antlr:antlr:jar:2.7.7:compile
[INFO] | | +- org.jboss:jandex:jar:2.0.0.Final:compile
[INFO] | | \- com.fasterxml:classmate:jar:1.3.0:compile
[INFO] | +- dom4j:dom4j:jar:1.6.1:compile
[INFO] | | \- xml-apis:xml-apis:jar:1.0.b2:compile
[INFO] | +- org.hibernate.common:hibernate-commons-annotations:jar:5.0.1.Final:compile
[INFO] | +- org.hibernate.javax.persistence:hibernate-jpa-2.1-api:jar:1.0.0.Final:compile
[INFO] | +- org.javassist:javassist:jar:3.20.0-GA:compile
[INFO] | \- org.apache.geronimo.specs:geronimo-jta_1.1_spec:jar:1.1.1:compile
[INFO] +- org.threeten:threetenbp:jar:1.3.1:compile
[INFO] +- org.postgresql:postgresql:jar:9.4-1206-jdbc42:compile
[INFO] +- org.springframework:spring-web:jar:4.2.4.RELEASE:compile
[INFO] +- com.fasterxml.jackson.core:jackson-core:jar:2.7.2:compile
[INFO] +- junit:junit:jar:4.12:test
[INFO] | \- org.hamcrest:hamcrest-core:jar:1.3:test
[INFO] +- org.mockito:mockito-core:jar:2.0.43-beta:test
[INFO] | +- net.bytebuddy:byte-buddy:jar:1.2.3:test
[INFO] | \- org.objenesis:objenesis:jar:2.1:test
[INFO] +- org.slf4j:slf4j-api:jar:1.7.19:runtime
[INFO] \- org.slf4j:jcl-over-slf4j:jar:1.7.19:runtime
應該有堆棧跟蹤顯示「ContextMapJsonAttributeConverter」的加載發生的位置,以及爲什麼無法加載。我懷疑JPA/Hibernate錯誤地將該類掃描到EMF下,但是這需要額外的配置,因此掃描失敗。鑑於您尚未在LocalContainerEntityManagerFactoryBean中定義packageToScan,我懷疑它是在persistence.xml中定義的,您可能會對其進行調整 –