【问题标题】:No autodetection of JPA Entities in maven-verify在 maven-verify 中没有自动检测 JPA 实体
【发布时间】:2011-06-20 15:02:51
【问题描述】:

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

在 Eclipse 中运行测试适用于这两种情况。

当 persistence.xml 位于 src/test 文件夹中时,有没有办法让自动检测为 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>

【问题讨论】:

    标签: java jpa build maven


    【解决方案1】:

    默认情况下,自动检测适用于与persistence.xml 相同的类路径项中的实体。可以通过&lt;jar-file&gt;元素配置。

    为了在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 中,我不确定如何使用它。

    【讨论】:

    • 很好,这很好用。 (至少在 Windows 中,我们需要在变量前添加一个 file: 前缀)。非常感谢!!!
    • 这个技巧也可以通过一个简单的片段来解决:&lt;jar-file&gt;../classes&lt;/jar-file&gt;
    【解决方案2】:

    如果您使用 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;
            }
        }
    

    弹簧配置:

    <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>
    

    【讨论】:

      猜你喜欢
      • 2013-04-11
      • 1970-01-01
      • 2014-07-22
      • 1970-01-01
      • 2021-07-23
      • 2014-02-19
      • 2011-04-18
      • 1970-01-01
      • 2017-07-22
      相关资源
      最近更新 更多