Нет автоматического определения сущностей JPA в maven-verify - PullRequest
8 голосов
/ 03 февраля 2011

Если я поместил файл persistence.xml в папку src / test / META-INF, автоопределение сущностей не будет работать с maven-verify. Когда файл persistence.xml находится в папке src / main / META-INF, он работает.

Запуск тестов в Eclipse работает в обоих случаях.

Есть ли способ заставить автоопределение работать для maven-verify, когда файл persistence.xml находится в папке src / test?

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 ]

20 голосов
/ 03 февраля 2011

По умолчанию автоопределение работает для сущностей в том же элементе classpath, что и 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.

0 голосов
/ 17 апреля 2013

Если вы используете 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 Config:

<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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...