在maven-verify中没有自动检测JPA实体

时间:2011-02-03 11:58:08

标签: java jpa build maven

如果我将persistence.xml放在src / test / META-INF文件夹中,则自动检测实体不能与maven-verify一起使用。当persistence.xml位于src / main / META-INF文件夹中时,它可以正常工作。

在两种情况下都可以在eclipse中运行测试。

当persistence.xml位于src / test文件夹中时,有没有办法让autodetection用于maven-verify?

的persistence.xml:

<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">

  <persistence-unit name="Unit" transaction-type="RESOURCE_LOCAL">
    <properties>
      <!-- Scan for annotated classes and Hibernate mapping XML files -->
      <property name="hibernate.archive.autodetection" value="class" />
    </properties>
  </persistence-unit>

</persistence>

2 个答案:

答案 0 :(得分:20)

默认情况下,自动检测适用于与persistence.xml相同的类路径项中的实体。它可以由<jar-file>元素配置。

persistence.xml位于src/test/resources/META-INF时启用正确的自动检测我使用以下技巧:

persistence.xml

<persistence ...>
    <persistence-unit ...>
        <jar-file>${project.build.outputDirectory}</jar-file>
        ...
    </persistence-unit>
</persistence>

pom.xml - 为src/test/resources启用资源过滤:

<project ...>
    ...
    <build>
        <testResources>
            <testResource>
                <directory>src/test/resources</directory>
                <filtering>true</filtering>
            </testResource>
        </testResources>
    </build>
</project>

如果persistence.xml实际上在src/test/META-INF,我不确定如何使用它。

答案 1 :(得分:0)

如果您使用Spring Framework,则可以使用PersistenceUnitPostProcessor

执行以下操作

<强> CustomPersistenceUnitPostProcessor:

    package com.yourpackage.utils.jpa.CustomPersistenceUnitPostProcessor;

    import java.util.HashSet;
    import java.util.List;
    import java.util.Set;
    import javax.persistence.Entity;
    import net.sourceforge.stripes.util.ResolverUtil;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.InitializingBean;
    import org.springframework.orm.jpa.persistenceunit.MutablePersistenceUnitInfo;
    import org.springframework.orm.jpa.persistenceunit.PersistenceUnitPostProcessor;

    /**
     * This PersistenceUnitPostProcessor is used to search given package list for JPA
     * entities and add them as managed entities. By default the JPA engine searches
     * for persistent classes only in the same class-path of the location of the
     * persistence.xml file.  When running unit tests the entities end up in test-classes
     * folder which does not get scanned.  To avoid specifying each entity in the persistence.xml
     * file to scan, this post processor automatically adds the entities for you.
     *
     */
    public class CustomPersistenceUnitPostProcessor implements PersistenceUnitPostProcessor, InitializingBean {

        private static final Logger log = LoggerFactory.getLogger(CustomPersistenceUnitPostProcessor.class);

        /** the path of packages to search for persistent classes (e.g. org.springframework). Subpackages will be visited, too */
        private List<String> packages;

        /** the calculated list of additional persistent classes */
        private Set<Class<? extends Object>> persistentClasses;

        /**
         * Looks for any persistent class in the class-path under the specified packages
         */
        @Override
        public void afterPropertiesSet() throws Exception {
            if (packages == null || packages.isEmpty())
                throw new IllegalArgumentException("packages property must be set");
            log.debug("Looking for @Entity in " + packages);
            persistentClasses = new HashSet<Class<? extends Object>>();
            for (String p : packages) {
                ResolverUtil<Object> resolver = new ResolverUtil<Object>();
                ClassLoader cl = this.getClass().getClassLoader();
                log.debug("Using classloader: " + cl);
                resolver.setClassLoader(cl);
                resolver.findAnnotated(Entity.class, p);
                Set<Class<? extends Object>> classes = resolver.getClasses();
                log.debug("Annotated classes:  " + classes);
                persistentClasses.addAll(classes);
            }
            if (persistentClasses.isEmpty())
                throw new IllegalArgumentException("No class annotated with @Entity found in: " + packages);
        }

        /**
         * Add all the persistent classes found to the PersistentUnit
         */
        @Override
        public void postProcessPersistenceUnitInfo(MutablePersistenceUnitInfo persistenceUnitInfo) {
            for (Class<? extends Object> c : persistentClasses)
                persistenceUnitInfo.addManagedClassName(c.getName());
        }

        public void setPackages(List<String> packages) {
            this.packages = packages;
        }
    }

Spring配置:

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="persistenceUnitName" value="thePersistenceUnitName" />
    <property name="persistenceXmlLocation" value="classpath:META-INF/persistence.xml" />
    <!-- reference to the XA datasource -->
    <property name="dataSource" ref="theDataSource" />        

    <property name="persistenceUnitPostProcessors">
        <list>
            <!-- custom implementation to avoid xml entity class declarations -->
            <bean class="com.yourpackage.utils.jpa.CustomPersistenceUnitPostProcessor">
                <property name="packages">
                    <list value-type="java.lang.String">
                        <value>com.yourpackage.model</value>
                    </list>
                </property>
            </bean>
        </list>
    </property>
</bean>

<强>的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://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
             version="1.0">

    <persistence-unit name="thePersistenceUnitName" transaction-type="RESOURCE_LOCAL">

        <provider>org.hibernate.ejb.HibernatePersistence</provider>

        <properties>            
            <property name="hibernate.format_sql" value="false" />
            <property name="hibernate.show_sql" value="false" />
            <property name="hibernate.use_sql_comments" value="false" />
            <property name="hibernate.generate_ddl" value="false" />
            <property name="hibernate.database_platform" value="org.hibernate.dialect.MySQLInnoDBDialect" />
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLInnoDBDialect" />

    </persistence-unit>
</persistence>