Comment configurer hibernate pour rechercher des entités dans un module différent

J’ai les modules A et B qui ont tous deux des classes annotées JPA. Le module B a un test unitaire qui extrait deux de ces entités de A. Les deux modules se comstacknt bien, les dépendances d’exécution sont définies correctement, mais l’erreur suivante s’affiche lorsque j’essaie d’exécuter le test unitaire:

java.lang.IllegalArgumentException: Unknown entity: MyClassHere Caused by: org.hibernate.MappingException: Unknown entity: MyClassHere 

Cela se produit dans l’appel EntityManager.merge.

Comme le module B contient tous les fichiers de configuration d’hibernation, etc., je suppose que ce n’est tout simplement pas de prendre en compte que ma classe de A est une entité.

J’ai essayé d’append ce qui suit à persistence.xml

 false 

Dans hibernate.cfg.xml, j’ai ajouté:

 myNamespace.* 

Alors:

    myNamespace.*   

Cela m’a donné une erreur que le contenu de “propriété” doit correspondre à null. Puis j’ai essayé:

  

Qu’est-ce que je rate?

Edit: Une chose que j’ai oublié de mentionner est que les deux modules sont configurés en tant que projets séparés (j’utilise eclipse), donc la structure des répertoires est différente. Les dépendances d’exécution sont toutes correctement configurées, mais comme les fichiers .class se retrouvent dans des répertoires différents, je pense que la mise en veille prolongée pourrait ne pas les parsingr.

  • Si vous utilisez Hibernate / Spring, nous pouvons étendre l’object LocalSessionFactoryBean et parcourir le projet pour identifier les classes d’entité du projet.
  • Puisque vous dites deux projets différents, essayez d’écrire un utilitaire de compilation pour parsingr les deux projets et créer un fichier XML d’entités qui résoudra votre problème.

Si vous configurez votre projet pour qu’il détecte automatiquement les entités, il parsingra uniquement le chemin d’access où se trouve le fichier META-INF / persistence.xml (par défaut).

En plus de :

 false 

Vous définissez une option d’hibernation supplémentaire:

  

Il détermine quel élément est détecté automatiquement par Hibernate Entity Manager.

Pour les entités supplémentaires (dans d’autres fichiers JAR), vous pouvez définir la section jar-file dans votre fichier persistence.xml principal:

   ... foo.bar.Entity1 foo.bar.Entity2 moduleB.jar ...   

L’élément jar-file spécifie les fichiers JAR visibles par l’unité de persistance empaquetée qui contiennent des classes de persistance gérées, tandis que l’élément class désigne explicitement les classes de persistance gérées.

Le fichier ou répertoire JAR dont le répertoire META-INF contient persistence.xml est appelé la racine de l’unité de persistance. La scope de l’unité de persistance est déterminée par la racine de l’unité de persistance. Chaque unité de persistance doit être identifiée par un nom unique dans son étendue.

Cordialement, André

persistence.xml peut contenir l’élément ....jar : spécifie un ou plusieurs fichiers JAR qui seront recherchés pour les classes.

Nous avons résolu un problème similaire sur le projet sur lequel je travaille en utilisant Spring pour détecter les entités. Par exemple, en utilisant une configuration Spring annotée:

 @Configuration @ComponentScan("com.org.prj.myNamespace1", "com.org.prj.myNamespace2") public class MyDatabaseConfig { @Bean public EntityManagerFactory entityManagerFactory() { final LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean(); // ...JPA properties, vendor adaptor, dialect, data source, persistence unit etc... factory.setPackagesToScan("com.org.prj.myNamespace1", "com.org.prj.myNamespace2"); factory.afterPropertiesSet(); return factory.getObject(); } // ...Data source beans etc... } 

J’ai récemment résolu un problème similaire en ajoutant le chemin d’access au fichier persistence.xml.

file:///C:/yourpath/yourJar.jar

J’espère que cela aide.

Le moyen simple de faire ça

 configuration.addAnnotatedClass(Contact.class) 

Si vous souhaitez utiliser l’parsing par package, commencez par charger toutes les classes à l’aide de ClassLoader . Voir l’exemple de code source de Hibernate-orm LocalSessionFactoryBuilder.class

 @Bean public SessionFactory sessionFactory(){ HibernateConfig configuration = new HibernateConfig(); Properties properties = hibernateProperties(); configuration.setProperties(properties); configuration.scanPackages("com.atcc.stom.model.entity"); return configuration.buildSessionFactory(); } 

HibernateConfig.class

 import org.hibernate.HibernateException; import org.hibernate.MappingException; import org.hibernate.cfg.Configuration; import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import org.springframework.core.io.support.ResourcePatternResolver; import org.springframework.core.io.support.ResourcePatternUtils; import org.springframework.core.type.classreading.CachingMetadataReaderFactory; import org.springframework.core.type.classreading.MetadataReader; import org.springframework.core.type.classreading.MetadataReaderFactory; import org.springframework.core.type.filter.AnnotationTypeFilter; import org.springframework.core.type.filter.TypeFilter; import org.springframework.util.ClassUtils; import javax.persistence.AtsortingbuteConverter; import javax.persistence.Embeddable; import javax.persistence.Entity; import javax.persistence.MappedSuperclass; import java.io.IOException; import java.lang.annotation.Annotation; import java.util.Set; import java.util.TreeSet; public class HibernateConfig extends Configuration { private static final TypeFilter[] DEFAULT_ENTITY_TYPE_FILTERS = new TypeFilter[] { new AnnotationTypeFilter(Entity.class, false), new AnnotationTypeFilter(Embeddable.class, false), new AnnotationTypeFilter(MappedSuperclass.class, false)}; private static final Ssortingng RESOURCE_PATTERN = "/**/*.class"; private static final Ssortingng PACKAGE_INFO_SUFFIX = ".package-info"; private final ResourcePatternResolver resourcePatternResolver; private static TypeFilter converterTypeFilter; static { try { @SuppressWarnings("unchecked") Class converterAnnotation = (Class) ClassUtils.forName("javax.persistence.Converter", Configuration.class.getClassLoader()); converterTypeFilter = new AnnotationTypeFilter(converterAnnotation, false); } catch (ClassNotFoundException ex) { // JPA 2.1 API not available - Hibernate <4.3 } } public HibernateConfig() { this(new PathMatchingResourcePatternResolver()); } public HibernateConfig(ClassLoader classLoader) { this(new PathMatchingResourcePatternResolver(classLoader)); } public HibernateConfig(ResourceLoader resourceLoader) { this.resourcePatternResolver = ResourcePatternUtils.getResourcePatternResolver(resourceLoader); } public void scanPackages(String... packagesToScan) throws HibernateException { Set entityClassNames = new TreeSet(); Set converterClassNames = new TreeSet(); Set packageNames = new TreeSet(); try { for (Ssortingng pkg : packagesToScan) { Ssortingng pattern = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + ClassUtils.convertClassNameToResourcePath(pkg) + RESOURCE_PATTERN; Resource[] resources = this.resourcePatternResolver.getResources(pattern); MetadataReaderFactory readerFactory = new CachingMetadataReaderFactory(this.resourcePatternResolver); for (Resource resource : resources) { if (resource.isReadable()) { MetadataReader reader = readerFactory.getMetadataReader(resource); Ssortingng className = reader.getClassMetadata().getClassName(); if (matchesEntityTypeFilter(reader, readerFactory)) { entityClassNames.add(className); } else if (converterTypeFilter != null && converterTypeFilter.match(reader, readerFactory)) { converterClassNames.add(className); } else if (className.endsWith(PACKAGE_INFO_SUFFIX)) { packageNames.add(className.subssortingng(0, className.length() - PACKAGE_INFO_SUFFIX.length())); } } } } } catch (IOException ex) { throw new MappingException("Failed to scan classpath for unlisted classes", ex); } try { ClassLoader cl = this.resourcePatternResolver.getClassLoader(); for (Ssortingng className : entityClassNames) { addAnnotatedClass(cl.loadClass(className)); } for (Ssortingng className : converterClassNames) { ConverterRegistrationDelegate.registerConverter(this, cl.loadClass(className)); } for (Ssortingng packageName : packageNames) { addPackage(packageName); } } catch (ClassNotFoundException ex) { throw new MappingException("Failed to load annotated classes from classpath", ex); } } private boolean matchesEntityTypeFilter(MetadataReader reader, MetadataReaderFactory readerFactory) throws IOException { for (TypeFilter filter : DEFAULT_ENTITY_TYPE_FILTERS) { if (filter.match(reader, readerFactory)) { return true; } } return false; } /** * Inner class to avoid hard dependency on JPA 2.1 / Hibernate 4.3. */ private static class ConverterRegistrationDelegate { @SuppressWarnings("unchecked") public static void registerConverter(Configuration config, Class converterClass) { config.addAtsortingbuteConverter((Class>) converterClass); } } } 
  • src / main / resources: applicationContext.xml
  • src / test / resources: test-applicationContext.xml

Assurez-vous que dans l’étendue du test, vous créez également votre contexte d’application pour parsingr ces entités. Votre test-applicationContext.xml peut ne pas configurer l’intégralité du contexte d’application au moment de l’exécution, mais certaines choses qui sont également nécessaires au moment du test doivent également être incluses, comme l’parsing de vos paquets.

Vous pouvez bien sûr créer un fichier persistence.xml dans src / main / resources et l’inclure à la fois dans applicationContext.xml et test-applicationContext.xml