sto correndo un programma con i seguenti componenti:WAS 6.1, JPA con JTA, Hibernate, Spring: problema di reperimento dei dati
- Oracle 9i
- WAS 6.1.0.23 con WS e EJB3 caratteristiche pacchetto
- JPA con Hibernate 3.3.2.GA come fornitore (con Hibernate-EntityManager 3.4.0)
- primavera gestore delle transazioni per WAS: UowTransactionManager (primavera 2.5.6) webflow
- primavera con la persistenza del flusso gestiti (2.0. 8), cioè il il gestore di entità viene serializzato nella sessione http e ripristinato su ogni richiesta.
In ogni richiesta che va dal controller Web al livello di servizio (annotato con @Transactional di primavera), ho notato che per ogni query SQL che Hibernate effettua durante l'invocazione del servizio all'interno della transazione, una nuova connnection DataSource è richiesto da jndi DataSource da ConnectionProvider di Hibernate, fino a quando DataSource esaurisce le connessioni libere e alla fine si blocca.
Ecco parti della configurazione:
Primavera:
<tx:annotation-driven /> <context:component-scan base-package="org.home.myapp" /> <jee:jndi-lookup id="dataSource" jndi-name="jdbc/DS" resource-ref="true"/> <bean id="transactionManager" class="org.springframework.transaction.jta.WebSphereUowTransactionManager"/> <bean id="EMF" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="jpaVendorAdapter"> <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/> </property> </bean>
persistence.xml
<persistence-unit name="persistence" transaction-type="JTA"> <properties> <property name="hibernate.archive.autodetection" value="class"/> <property name="hibernate.dialect" value="org.hibernate.dialect.Oracle9iDialect"/> <property name="hibernate.current_session_context_class" value="jta"/> <property name="hibernate.cache.provider_class" value="org.hibernate.cache.NoCacheProvider"/> <property name="hibernate.format_sql" value="true"/> <property name="hibernate.show_sql" value="true"/> <property name="hibernate.default_batch_fetch_size" value="20"/> <property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.WebSphereExtendedJTATransactionLookup"/> </properties> </persistence-unit>
Servizio
@Transactional(readOnly=true) @Service public class MyServiceImpl implements MyService { @Autowired MyDao dao; public void getSomething() { dao.findSomething(); } }
DAO
@Repository public class MyDaoJap implements MyDao { @PersistenceContext EntityManager em; public void findSomething() { em.find(...); } }
Nota della transazione è di sola lettura, che è normale per il flusso di persistenza: solo l'ultimo di transizione (con commit = true) invoca un metodo transazionale non readOnly. L'attivazione del flag readOnly attiva automaticamente la modalità di scarico Hibernate su MANUAL.
Mentre si fa un po 'di debug, ho notato quanto segue:
- Il gestore delle transazioni UOW è correttamente invocato nella catena intercettazione del servizio, il che suggerisce che una transazione è attiva
- Hibernate richiede una connessione invocando DataSource.getConnection() sul DataSource non elaborato che viene iniettato nell'EMF; La strategia per ottenere una connessione proviene da InjectedDataSourceConnectionProvider di Hibernate e questa classe fa riferimento a WAS DataSource (non un proxy a conoscenza di una transazione attiva o simile).
Immagino che il problema sia in questo secondo punto, ma non riesco a trovare un errore nella mia configurazione. Qualcuno può aiutare?
Grazie per il vostro aiuto.
La seconda è la risposta corretta. L'ambito di condivisione di DataSource era Unsharable. Grazie mille. – Gaetan