9

If I put the persistence.xml in the src/test/META-INF folder, autodetection the Entities does not work with maven-verify. When the persistence.xml is located in the src/main/META-INF folder it works.

Running the tests in eclipse works in both cases.

Is there a way to get autodetection to work for maven-verify when the persistence.xml is located in the src/test Folder?

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>
Dominik
  • 1,241
  • 1
  • 14
  • 31

2 Answers2

22

By default autodetection works for entities in the same classpath item as persistence.xml. It can be configured by <jar-file> elements.

To enable correct autodetection when persistence.xml is in src/test/resources/META-INF I use the following trick:

persistence.xml:

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

pom.xml - enable resource filtering for src/test/resources:

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

Though I'm not sure how to use it if your persistence.xml is actually in src/test/META-INF.

axtavt
  • 239,438
  • 41
  • 511
  • 482
0

If you use Spring Framework you can do the following with a 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>
dukethrash
  • 1,449
  • 4
  • 15
  • 25