2012-02-29 17 views
6

Ho una configurazione di progetto in cui ho modularizzato un progetto e ho inserito un modulo in un file jar che viene incluso nel progetto principale quando creiamo una guerra e la distribuiamo. Il problema che sto affrontando è che, ho un Entity presente nel modulo che non si carica quando il contenitore JPA EntityManagerFactory per unitName viene costruito durante l'avvio.Caricamento entità JPA da file Jar esterno

La domanda di base che ho è la ricerca di EntityManager sul persistence.xml e quindi caricare le proprietà che sono specificate e quindi eseguire la scansione di tutti i pacchetti per l'annotazione @Entity?

Qualche idea su come funziona e come posso risolvere questo sarebbe grandioso.

Ho trovato questo collegamento e menziona sulla creazione di unità persistence separate, ma qui non ho bisogno di un'unità di persistenza separata. Ho solo bisogno del modulo per tornare indietro sul progetto principale e caricare l'entità e qualsiasi altra classe @Resource, @Component, che fa a causa del contesto: scansione dei componenti e la configurazione dell'annotazione.

http://javathoughts.capesugarbird.com/2009/02/jpa-and-multiple-persistence-units.html

Ecco il mio codice/configurazione

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
    <property name="dataSource" ref="dataSource" /> 
    <property name="persistenceUnitName" value="LineManagement" /> 
    <property name="jpaVendorAdapter"> 
     <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> 
      <property name="generateDdl" value="false" /> 
      <property name="showSql" value="false" /> 
      <property name="databasePlatform" ref="cpsHibernateDialectClassName" /> 
     </bean> 
    </property> 
    <property name="beanName" value="entityManager"></property> 
</bean> 

definizione del EnitityManagerFactory per l'avvio del gestore di entità.

<persistence-unit name="LineManagement" transaction-type="RESOURCE_LOCAL"> 
    <properties> 
     <property name="hibernate.id.new_generator_mappings" value="true" /> 
     <property name="hibernate.current_session_context_class" value="thread" /> 
     <property name="hibernate.default_batch_fetch_size" value="200" /> 

....

persistence.xml che definisce il secondo livello di cache e altre proprietà Sospensione.

Quindi, il modulo che ha un'entità.

import javax.persistence.Entity; 


@Entity 
@Table(name = IntegrationEvent.TABLE_NAME, uniqueConstraints = @UniqueConstraint(columnNames = "INTGRTN_EVNT_QUEUE_SK")) 
@GenericGenerator(name = "UUID_GEN", strategy = "org.hibernate.id.UUIDHexGenerator",  parameters = { @Parameter(name = "separator", value = "-") }) 
public class IntegrationEvent implements Serializable { 

.... }

Nota: l'entità è in un pacchetto diverso da quello del genitore, dal momento che è un modulo separato per conto suo.

L'entità che carica bene nel progetto principale.

package com.parent.line.entity; 

import javax.persistence.Entity; 

@Entity 
@Table(name = "ACCOUNT") 
@Cacheable(true) 
public class Account 
    implements LMLookupTypeEntityByDivision, Serializable, Comparable<Account> { 
+1

Il problema era dovuto al fatto che il modulo è stato aggiunto come dipendenza al mio progetto padre poiché è completamente separato. Quindi sarebbe inserito nella mia cartella WEB-INF/lib. Dopo aver eseguito il debug del codice JPA dove carica le entità, mi sono reso conto che il classpath in cui inizia la scansione delle annotazioni @Entity proveniva dalle classi WEB-INF /. il che ha senso, dal momento che lib è di sola lettura. ora, devo pensare di aggiungere il modulo nella cartella classes o usare il tag nel persistence.xml in qualche modo per abilitare l'entità jar a essere scansionata e caricata – Hrishikesh

risposta

4

Per analizzare entità residenti in jar, è necessario includerlo in persistence.xml. <jar-file>packedEntity.jar</jar-file>.

Se si desidera caricare l'unità dal pacchetto, è possibile provare a iniettarlo direttamente dal barattolo. @PersistenceContext(unitName = "../packedEntity.jar#main")

non ho provato, ma è possibile attivare il rilevamento automatico di sospensione per le entità <property name="hibernate.archive.autodetection" value="class, hbm"/>

1

Al lavoro non usiamo JPA ma Hibernate, e il nostro progetto è totalmente modulare. Gestiamo circa 30 paesi che non utilizzano gli stessi moduli e siamo in grado di caricare tutte le entità di questi moduli in una factory di sessione semplicemente cambiando le dipendenze di maven (nessun file orm da modificare)

La soluzione utilizzata è quella di utilizzare l'SPI Java. ServiceLoader cerca le classi che implementano un'interfaccia principale EntityProvider. Ogni EntityProvider di ogni modulo eseguirà l'hardcoded delle entità che porta e restituirà un elenco di entità quando chiama ServiceLoader.load (EntityProvider.class). Quindi nel core della piattaforma abbiamo solo bisogno di creare un factory di sessione basato sulla primavera in cui forniamo l'elenco delle entità da un bean factory che chiamerà lo SPI.

Non so se sarà facile con JPA ma sono abbastanza sicuro che sia possibile ma potrebbe essere necessario creare manualmente l'EMF da un contesto primaverile, e anche il PersistenceUnit suppongo ... Che cosa si può voglio è un'unità di persistenza che è un "unione" delle unità di persistenza di tutti i tuoi moduli (almeno per le tue entità) Dai un'occhiata a SPI e anche al pacchetto javax.persistence.spi.

Controllare anche come creare un EMF con la Primavera: AbstractEntityManagerFactoryBean

Edit: è possibile controllare questo: using the MergingPersistenceUnitManager to load entity

0

se si utilizza avvio primavera usare l'annotazione di scansione entità nella classe springboot principale

@EntityScan(
     basePackageClasses = {externalpackage.classname.class} 
) 
Problemi correlati