【问题标题】:Spring Data JPA - Multiple Persistence Units working as JUnit, but not in TomcatSpring Data JPA - 多个持久性单元作为 JUnit 工作,但不在 Tomcat 中
【发布时间】:2014-01-29 03:22:21
【问题描述】:

我几乎已经准备好重新使用我舒适的 JDBC 模板,但我想看看社区是否有任何见解。我在我的基于 Spring 的应用程序中添加了第二组 JPA 框架对象:新的实体管理器、持久性单元等。现有的实体管理器使用 ObjectDB 来实现持久性,我想将光滑的 Spring Data JPA API 用于 CRUD 存储库(Hibernate作为一个实现),但它一直给我带来麻烦。我以为我已经在本地解决了所有问题 b/c 我有一个 JUnit 可以通过 bean 创建,但是一旦我将这些 bean 放入 applicationContext 我有一个回归,我不知道如何修复

从 com.xxx 中删除公司名称的 JUnit 和应用程序上下文 XML sn-p

<context:annotation-config />
<context:component-scan base-package="com"/>
<jpa:repositories base-package="com.dms.server.mode" entity-manager-factory-ref="emf"/>
<!-- TxMgr #1 -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="emf" />
</bean>
<!-- EMF #1 -->
<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" p:dataSource-ref="dataSource">
    <property name="persistenceUnitName" value="hibernate-pu" />
    <property name="persistenceXmlLocation" value="classpath:META-INF/persistence-hibernate.xml"/>
    <property name="persistenceProviderClass" value="org.hibernate.ejb.HibernatePersistence"/>
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
    </property>
    <property name="jpaProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
            <prop key="hibernate.show_sql">true</prop>
        </props>
    </property>
</bean>


<bean id="sharedModeManager" class="com.dms.server.mode.DefaultSharedModeManager"/>
<bean id="changeRecordCommandFactory" class="com.dms.server.ChangeRecordCommandFactory"/>

<bean id="createModeCommand" class="com.dms.server.mode.CreateModeCommand">
    <property name="apsConnection" ref="ApsConnection" />
</bean>

<!-- TxMgr #2 -->
<bean id="EnvDMSTxManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="EnvDMSEntityManagerFactory"/>
</bean>
<!-- EMF #2 -->
<bean id="EnvDMSEntityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="persistenceUnitName" value="envService"/>
    <property name="persistenceXmlLocation" value="classpath:META-INF/persistence.xml"/>
    <property name="persistenceProviderClass" value="com.objectdb.jpa.Provider"/>
</bean>

persistence-hibernate.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="hibernate-pu" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <mapping-file>META-INF/orm-none.xml</mapping-file>
    <class>com.api.dms.SharedMode</class>
    <class>com.api.dms.SharedModeAssignment</class>
    <exclude-unlisted-classes>true</exclude-unlisted-classes>
    <properties>
        <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" />
        <property name="hibernate.hbm2ddl.auto" value="validate" />
        <property name="hibernate.show_sql" value="true" />
    </properties>
</persistence-unit>

persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="envService" transaction-type="RESOURCE_LOCAL">
    <provider>com.objectdb.jpa.Provider</provider>
    <mapping-file>META-INF/orm-objectdb.xml</mapping-file>
    <class>com.awareness.server.environment.SampleIndicationHistory</class>
    <exclude-unlisted-classes>true</exclude-unlisted-classes>
    <properties>
        <property name="javax.persistence.jdbc.url" value="$temp/awp/envService.odb" />
        <property name="javax.persistence.jdbc.user" value="admin" />
        <property name="javax.persistence.jdbc.password" value="admin" />
    </properties>
</persistence-unit>

orm-none.xml(一切都是通过注解拾取的,但如果我不指定这个文件,就会拾取另一个orm文件)

<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_1_0.xsd" version="1.0">
</entity-mappings>

orm-objectdb.xml

<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_2_0.xsd" version="2.0">
<entity class="com.awareness.server.environment.SampleIndicationHistory" access="FIELD">
    <table name="SAMPLE_IND_HISTORY"/>
    <attributes>
        <id name="deviceId"/>
        <basic name="tOldest"/>
        <basic name="tNewest"/>
        <element-collection name="timestamps"/>
        <element-collection name="indexes"/>
    </attributes>
</entity>

再一次,这一切在 JUnit 中都能正常工作

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"/com/junit-context.xml"})
// Functioning JUnit

但是在 Tomcat 中失败了

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sharedModeManager': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sharedModeRepository': FactoryBean threw exception on object creation; nested exception is java.lang.IllegalArgumentException: Not an managed type: class com.api.dms.SharedMode
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:306)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1116)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:323)
... 33 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sharedModeRepository': FactoryBean threw exception on object creation; nested exception is java.lang.IllegalArgumentException: Not an managed type: class com.api.dms.SharedMode
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:149)
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:102)
at org.springframework.beans.factory.support.AbstractBeanFactory.getObjectForBeanInstance(AbstractBeanFactory.java:1454)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:249)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:198)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.autowireResource(CommonAnnotationBeanPostProcessor.java:442)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.getResource(CommonAnnotationBeanPostProcessor.java:416)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor$ResourceElement.getResourceToInject(CommonAnnotationBeanPostProcessor.java:550)
at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:150)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:303)
... 41 more
Caused by: java.lang.IllegalArgumentException: Not an managed type: class com.api.dms.SharedMode
at org.hibernate.ejb.metamodel.MetamodelImpl.managedType(MetamodelImpl.java:171)
at org.springframework.data.jpa.repository.support.JpaMetamodelEntityInformation.<init>(JpaMetamodelEntityInformation.java:68)
at org.springframework.data.jpa.repository.support.JpaEntityInformationSupport.getMetadata(JpaEntityInformationSupport.java:65)
at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getEntityInformation(JpaRepositoryFactory.java:146)
at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:84)
at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:67)
at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:150)
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.getObject(RepositoryFactoryBeanSupport.java:162)
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.getObject(RepositoryFactoryBeanSupport.java:44)
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:142)
... 51 more

Java 类

@Repository
@PersistenceContext(unitName="hibernate-pu")
public interface SharedModeRepository extends CrudRepository<SharedMode, SharedModeKey> {
Iterable<SharedMode> findByName(String name);
Iterable<SharedMode> findByCurrent(boolean current);
SharedMode findBySharedModeKeyIdAndCurrent(int id, boolean current);
}

@PersistenceContext(name="hibernate-pu")
@Entity(name="shared_mode")
@XmlRootElement(name="sharedMode")
public class SharedMode implements Comparable<SharedMode>, ModeLike, Serializable {
    private static final long serialVersionUID = -3202319961514321359L;
    @EmbeddedId
    @XmlElement
    private SharedModeKey sharedModeKey = new SharedModeKey();
    @Column
    private String name;
    @Column
    private boolean current;
    ...
}

很难知道在启动过程中做了什么不同的事情会导致失败,我一直在逐步检查很多框架代码,试​​图确定到底出了什么问题。

【问题讨论】:

    标签: java spring hibernate jpa


    【解决方案1】:

    您得到的最后一个异常意味着 JPA 提供程序无法识别您的 bean。当您使用 Spring 时,您可以将 entityManagerFactory 上的 packagesToScan 属性设置为包含您的实体的包,以使 JPA 提供程序能够找到它们。或者,您可以使用 persistence.xml 并列出那里的所有实体。

    【讨论】:

    • Ean,请看persistence-hibernate.xml,我确实在堆栈跟踪中列出了被投诉的 bean
    • 尝试将它们放在 persistence.xml 中,因为 Spring 中存在与这些 JPA 配置文件相关的旧错误。 (当时我不记得那是什么了)
    • 它最终成为我的设置中的一个错误,其中 JAR 中的实体和 persistence.xml 位于另一个 JAR 中。
    猜你喜欢
    • 2018-05-11
    • 1970-01-01
    • 1970-01-01
    • 2015-03-03
    • 1970-01-01
    • 2013-02-15
    • 1970-01-01
    • 2011-04-21
    • 2017-06-01
    相关资源
    最近更新 更多