2011-09-16 15 views
21

Stiamo sviluppando un'applicazione Web con Spring, Hibernate e Maven in modo molto modulare. Esistono progetti chiave che definiscono l'accesso ai dati e visualizzano specifiche cose, quindi ci sono moduli che definiscono la logica e le entità (@Entity) e poi c'è l'app Web che definisce controller e vista.JPA - più jar che definiscono gli oggetti @Entity

Ora abbiamo un modulo di protezione che definisce entità di sicurezza come account e ruolo e abbiamo un modulo prototipo che definisce alcune entità di esempio come cliente e ordine. Entrambi hanno un valore PersistenceUnit definito all'interno di uno persistence.xml che è praticamente vuoto eccetto il nome PersistenceUnit, poiché tutta la configurazione del database viene eseguita nell'app Web con un datasource.xml. Si suppone che l'app Web carichi entrambi i jar come dipendenze Maven.

Entrambi i progetti si costruiranno bene, analizzeranno automaticamente tutte le entità e le creeranno per i rispettivi test unitari. Verranno anche caricati all'interno dell'app Web con successo se aggiunti singolarmente.

Tuttavia, non appena vengono caricati entrambi allo stesso tempo, il secondo sostituisce lo PersistenceUnit del primo e quindi crea uno per tutte le entità dal primo. Se entrambi i progetti hanno un'unità di persistenza diversa, il caricamento dell'applicazione Web genera un'altra eccezione che indica che è stato definito no single default persistence unit.

Quindi .. come posso ottenere tutte le classi annotate @Entity per caricare nella mia web app senza dover definire tutti all'interno del persistence.xml (come here), ma piuttosto tramite componente di scansione? This sembra come un'idea, anche se non so come usarlo e testarlo ...

Penso che sia dobbiamo unire tutti PersistenceUnits dentro l'applicazione web o caricare tutte le Entità a livello di codice. Definirli hard-coded all'interno di persistence.xml non è un'opzione per noi.

+0

relativa alla prima risposta: Per quanto ne so , Spring esegue già la scansione delle classi annotate e le aggiunge a PersistenceUnit'. Il problema è che devo nominare tutte le "PersistenceUnits" le stesse che risulteranno sovrascritte l'una dall'altra. Quindi sono alla ricerca di un modo per unire tutti PersistenceUnits in uno nella mia web app. Non so se [questo] [1] (in basso) farebbe, anche se non ho idea di dove registrare un 'MergingPersistenceUnitPostProcessor' [1]: http://forum.springsource.org/showthread.php? 61763-Problemi-con-JPA-e-multiple-persistenza-unità – Pete

risposta

4

Utilizziamo un layout di modulo simile, ma posizioniamo il contesto di persistenza nella parte di guerra della nostra applicazione e inseriamo l'entitymanager nei DAO dei moduli. Fatta eccezione per il test dell'unità, , i moduli non hanno un PU. Abbiamo fatto questo perché avevamo paura, , che una transazione che si estendeva su più moduli potesse causare problemi.

Nel DAO

@PersistenceContext 
private EntityManager em; 

Nella persistance.xml è necessario arruolare tutti i soggetti con gli elementi.

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

ecc

+1

Vedo .. Ho provato questo approccio e funziona . Ma non è alquanto complicato dover aggiornare sempre il file persistence.xml (più i file unit test persistence.xml)? Non esiste un modo dinamico per caricare tutto automaticamente? – Pete

+2

In teoria esiste una funzione di scansione automatica del runtime (dipende dal provider JPA? Non sono sicuro) ma ho riscontrato che non sempre funziona. Nella mia azienda, ho scritto un plugin Maven, che corrono nel progetto di guerra quando si costruisce, per generare automaticamente base di persistence.xml su tutte le classi annotate @Entity nel classpath. –

+0

buona idea, che è almeno un po 'automatizzato e sarebbe in grado di fornire l'ultimo persistence.xml prima dell'esecuzione unit test. Puoi postare qualche puntatore agli elementi chiave del tuo plugin? Non l'ho fatto prima ... (posso già pensare a un secondo caso d'uso per questo, vale a dire creare tipi di query per queryDSL, dato che l'ultimo plugin sembra essere rotto) – Pete

3

Le classi saranno nel caricatore classe.

Questa è la risposta Scanning Java annotations at runtime.

È quello che vuoi? Per cercare @Entity annotato e aggiungerli a un PersistenceUnit?

Saluti.

+0

+1 come ho bisogno di questo presto per la scansione di @PreAuthorize Annotazioni – Pete

+0

@Pete grazie! Ç – ssedano

3

Bene, noi' re avendo un problema simile sul nostro ciclo di sviluppo. Se le entità di riferimento sono in un altro -ejb.file jar (questo è il nostro caso) è possibile associare queste entità con

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

tag. Si noti che si dovrebbe includere anche una persistence.xml nella cartella dependent-entities-ejb.jar s' META-INF. Ulteriori informazioni possono essere trovate here.

4

Poiché la domanda sembra ricevere ancora attenzione, pubblicherò la nostra ultima soluzione al problema.

Siamo ora scansione automatica di tutti i pacchetti invece di utilizzare persistence.xml file ovunque.

Nel nostro datasource.xml abbiamo aggiunto la linea di

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

Quasi completo 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" /> 

+0

Ma questo non aiuta se non si avvia l'applicazione. Non sarai in grado di generare metamodelli statici usando questa configurazione. – kboom

Problemi correlati