web-dev-qa-db-fra.com

JPA - plusieurs jars définissant des objets @Entity

Nous développons une application Web avec Spring, Hibernate et Maven de manière très modulaire. Il existe des projets principaux définissant l'accès aux données et l'affichage d'éléments spécifiques, puis des modules définissant la logique et les entités (@Entity), puis l'application Web définissant le contrôleur et la vue.

Nous disposons maintenant d’un module de sécurité définissant des entités de sécurité telles que le compte et le rôle, et d’un prototype de module définissant des exemples d’entités, telles que client et commande. Les deux ont une PersistenceUnit définie dans un persistence.xml qui est à peu près vide, à l'exception du nom de PersistenceUnit, étant donné que toute la configuration de la base de données est effectuée dans l'application Web avec un datasource.xml. L'application Web est censée charger les deux fichiers jar en tant que dépendances maven.

Les deux projets construiront correctement, en analysant automatiquement toutes les entités et en les créant pour leurs tests unitaires respectifs. Ils seront également chargés dans l'application Web avec succès s'ils sont ajoutés individuellement. 

Cependant, dès que les deux sont chargés en même temps, le second remplace la PersistenceUnit de la première et crée ainsi un IllegalArgumentException : Not an entity pour toutes les entités de la première. Si les deux projets ont une unité de persistance différente, le chargement de l'application Web générera une autre exception indiquant que no single default persistence unit est défini.

Alors… comment puis-je obtenir le chargement de toutes les classes annotées @Entity dans mon application web sans avoir à les définir toutes dans le persistence.xml (comme ici ) mais plutôt via l'analyse de composant? Ceci semble être une idée, bien que je ne sache pas l’utiliser et la tester ...

Je pense que nous devons soit fusionner tous les PersistenceUnits dans l'application Web, soit charger toutes les entités par programme. Les définir en dur dans le fichier persistence.xml n'est pas une option pour nous.

23
Pete

Nous utilisons une disposition de module similaire, Mais nous plaçons le contexte de persistance dans la partie war de notre application et injectons le entitymanager dans les DAO des modules. Sauf pour les tests unitaires, Les modules n'ont pas de PU. Nous l'avons fait parce que nous craignions, qu'une transaction couvrant plusieurs modules puisse causer des problèmes.

Dans le DAO

@PersistenceContext
private EntityManager em;

Dans le fichier persistance.xml, vous devez associer toutes les entités aux éléments.

<persistence-unit name="myPU">
    <class>com.Entity1</class>      
<class>com.Entity2</class>

etc.

4
stacker

Puisque la question semble toujours attirer l'attention, je vais poster notre dernière solution au problème.

Nous sommes maintenant analysant automatiquement tous les paquets au lieu d'utiliser les fichiers persistence.xml n'importe où.

Dans notre datasource.xml nous avons ajouté la ligne 

<property name="packagesToScan" value="our.basepackage" />

Presque complet datasource.xml:

<!-- Bean definition here -->

<bean id="ourDataSource"
    class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver" />
            <!-- define connection properties -->       
</bean>


<bean id="entityManagerFactory"
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="ourDataSource" />
    <property name="packagesToScan" value="our.basepackage" />
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
            <property name="showSql" value="false" />
            <property name="generateDdl" value="true" />
            <property name="databasePlatform" value="org.hibernate.dialect.MySQL5InnoDBDialect" />
        </bean>
    </property>

</bean>

<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager" />

4
Pete

Eh bien, nous avons un problème similaire sur notre cycle de développement. Si vos entités référençantes se trouvent dans un autre fichier -ejb.jar (c'est notre cas), vous pouvez les lier avec 

<jar-file>relativePathToYourJar/dependent-entities-ejb.jar</jar-file> 

étiquette. Notez que vous devez également inclure un dossier persistence.xml sous le dossier code META-INF de dependent-entities-ejb.jar. Des informations complémentaires pourraient être trouvées ici .

3
tugcem

Les classes seront dans le chargeur de classes.

This so answer Analyse des annotations Java au moment de l'exécution .

Est-ce que c'est ce que tu veux? Pour analyser @Entity annoté et les ajouter à une PersistenceUnit?

Cordialement.

3
ssedano

J'ai mis au point une solution comme tugcem, mais comme j'utilise Maven, je ne voudrais pas que les numéros de version de jar figurent dans mon fichier persistence.xml. La solution que j'ai proposée est décrite ici: JPA 2.0: Ajout de classes d'entités à PersistenceUnit * à partir de différents fichiers jar * automatiquement

0
Jesper Tejlgaard