À l'aide de Plusieurs gestionnaires d'entités dans DAO
Je suis en train de configurer Spring+Hibernate+JPA pour le travail avec les deux bases de données ( un pour écrire que j'ai.e insertion & mise à jour & autre est uniquement à des fins de récupération.
J'ai fait quelques recherches & trouvé ces solutions possibles:
- http://www.studytrails.com/frameworks/spring/spring-hibernate-jpa.jsp
- Plusieurs bases de données avec Spring+Hibernate+JPA
- Comment se connecter à plusieurs bases de données en utilisant JPA?
Mais je suis bloqué à un endroit, & erreur
No qualifying bean of type [javax.persistence.EntityManagerFactory] is defined: expected single matching bean but found 2: entityManagerFactoryReadOnly,entityManagerFactoryWriteOnly
Ce que je fais mal ?
persistent.read.only.xml:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="readOnly" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>com.demo.domain.Contact</class>
</persistence-unit>
</persistence>
persistent.write.only.xml:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="writeOnly" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>com.demo.domain.Contact</class>
</persistence-unit>
</persistence>
mcv-dispatcher-servlet.xml:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:lang="http://www.springframework.org/schema/lang" xmlns:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:util="http://www.springframework.org/schema/util"
xmlns:oxm="http://www.springframework.org/schema/oxm"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd
http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm-3.2.xsd">
<!-- Activates various annotations to be detected in bean classes -->
<context:annotation-config />
<!-- Scans the classpath for annotated components that will be auto-registered
as Spring beans. For example @Controller and @Service. Make sure to set the
correct base-package -->
<context:component-scan base-package="com.demo" />
<!-- Setup a simple strategy: 1. Take all the defaults. 2. Return XML by
default when not sure. -->
<!-- Total customization - see below for explanation. -->
<bean id="cnManager"
class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
<property name="favorPathExtension" value="true" />
<property name="ignoreAcceptHeader" value="true" />
<property name="defaultContentType" value="application/json" />
<property name="useJaf" value="false" />
<property name="mediaTypes">
<map>
<entry key="json" value="application/json" />
<entry key="xml" value="application/xml" />
</map>
</property>
</bean>
<!-- Make this available across all of Spring MVC -->
<mvc:annotation-driven
content-negotiation-manager="cnManager" />
<bean class="com.demo.view.MvcConfiguringPostProcessor" />
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
p:location="/WEB-INF/jdbc.properties" />
<!-- ******************************************************************** -->
<!-- START: Multiple C3P0 data-sources for DB instance -->
<!-- ******************************************************************** -->
<!-- https://stackoverflow.com/questions/12922351/can-i-use-multiple-c3p0-datasources-for-db-instance -->
<!-- Using Apache DBCP Data Sources -->
<bean id="dataSource"
abstract="true" >
<property name="driverClass" value="${db.driverClassName}" />
<property name="user" value="${db.username}" />
<property name="password" value="${db.password}" />
<property name="idleConnectionTestPeriod" value="${db.idleConnectionTestPeriod}" />
<property name="preferredTestQuery" value="select 1" />
<property name="testConnectionOnCheckin" value="true" />
</bean>
<bean id="dataSourceReadOnly"
parent="dataSource"
class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="jdbcUrl" value="${db.readOnlyDataBaseUrl}" />
</bean>
<bean id="dataSourceWriteOnly"
parent="dataSource"
class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="jdbcUrl" value="${db.writeOnlyDataBaseUrl}" />
</bean>
<!-- ******************************************************************** -->
<!-- END: Multiple C3P0 data-sources for DB instance -->
<!-- ******************************************************************** -->
<bean id="jpaVendorProvider"
class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="database" value="MYSQL" />
<property name="databasePlatform" value="${db.dialect}" />
<property name="showSql" value="true" />
<property name="generateDdl" value="true" />
</bean>
<!-- <bean -->
<!-- class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"> -->
<!-- <property name="defaultPersistenceUnitName" value="readOnly" /> -->
<!-- </bean> -->
<bean id="persistenceUnitManager"
class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
<!-- defining multiple persistence unit -->
<property name="persistenceXmlLocations">
<list>
<value>/META-INF/persistence.read.only.xml</value>
<value>/META-INF/persistence.write.only.xml</value>
</list>
</property>
<property name="defaultDataSource" ref="dataSourceReadOnly" />
<property name="dataSources">
<map>
<entry key="readOnlyDsKey" value-ref="dataSourceReadOnly" />
<entry key="writeOnlyDsKey" value-ref="dataSourceWriteOnly" />
</map>
</property>
</bean>
<bean id="entityManagerFactoryReadOnly"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<!-- <property name="dataSource" ref="dataSourceReadOnly" /> -->
<property name="persistenceUnitManager" ref="persistenceUnitManager" />
<property name="jpaVendorAdapter" ref="jpaVendorProvider" />
<property name="persistenceUnitName" value="readOnly" />
<!-- entityManagerFactory does not specify persistenceUnitName property
because we're defining more than one persistence unit -->
<!-- <property name="persistenceUnitName" value="hello_mysql" /> -->
<!-- <property name="persistenceXmlLocation" value="/META-INF/persistence.xml" /> -->
</bean>
<bean id="entityManagerFactoryWriteOnly"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<!-- <property name="dataSource" ref="dataSourceWriteOnly" /> -->
<property name="persistenceUnitManager" ref="persistenceUnitManager" />
<property name="jpaVendorAdapter" ref="jpaVendorProvider" />
<property name="persistenceUnitName" value="writeOnly" />
</bean>
<!-- ******************************************************************** -->
<!-- Mark bean transactions as annotation driven -->
<!-- ******************************************************************** -->
<tx:annotation-driven transaction-manager="transactionManagerReadOnly" />
<tx:annotation-driven transaction-manager="transactionManagerWriteOnly" />
<!-- ******************************************************************** -->
<!-- Setup the transaction manager -->
<!-- ******************************************************************** -->
<bean id="transactionManagerReadOnly" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactoryReadOnly" />
</bean>
<bean id="transactionManagerWriteOnly" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactoryWriteOnly" />
</bean>
</beans>
Mon DAO:
package com.demo.dao;
import java.util.Collections;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import com.demo.domain.Contact;
//import java.util.Collections;
@Repository("ContactDAO")
@Transactional
public class ContactDAOImpl extends AppDAOimpl<Contact> implements ContactDAO {
/**
*
*/
private static final long serialVersionUID = 3986253823316728444L;
/**
* EntityManager injected by Spring for persistence unit MYSQL
*
*/
@PersistenceContext(unitName = "readOnly")
@Qualifier("entityManagerFactoryReadOnly")
private EntityManager entityManager;
/**
* Get the entity manager that manages persistence unit MYSQL
*
*/
public EntityManager getEntityManager() {
return entityManager;
}
/**
* EntityManager injected by Spring for persistence unit MYSQL
*
*/
@PersistenceContext(unitName = "writeOnly")
@Qualifier("entityManagerFactoryWriteOnly")
private EntityManager woEntityManager;
/**
* Get the entity manager that manages persistence unit MYSQL
*
*/
public EntityManager getWoEntityManager() {
return woEntityManager;
}
//other functions goes here
}
À la fois les bases de données ont le même schéma ( lire &écrire ).
Pouvez-vous montrer comment l'entité? avez-vous ajouter de la déclaration de schéma sur le dessus de la enitity?
Je n'ai pas ajouter n'importe quel schéma en haut de ma classe d'entité .
Je n'ai pas ajouter n'importe quel schéma en haut de ma classe d'entité .
OriginalL'auteur anasanjaria | 2014-01-09
Vous devez vous connecter pour publier un commentaire.
& ici est bon tutoriel sur l'intégration de la JTA avec le printemps.
http://www.javacodegeeks.com/2013/07/spring-jta-multiple-resource-transactions-in-tomcat-with-atomikos-example.html
OriginalL'auteur anasanjaria
Ajouter deux classes
ContactWrite.java
sur le dessus de déclarer le schéma et le tableau ci-dessous
Faire la même chose pour l'autre table dans la DB2
ContactRead.java
Maintenant l'utilisation de ces deux classes dans la persistance des fichiers xml comme ci-dessous.
persistent.read.only.xml:
persistent.write.only.xml:
Oui, vous avez raison, c'est un peu fastidieux, vous pouvez étendre la 2ème entité à partir de la première. Je vois certains commentaires ici coderanch.com/t/598699/ORM/databases/... je ne sais pas comment cela peut être fait en JPA.
J'ai essayé votre solution , il est toujours de me donner la même erreur. J'ai trouvé cette solution mais je ne suis pas en mesure de l'obtenir ( concernant la configuration de point de vue ) stackoverflow.com/questions/1961566/...
OriginalL'auteur Zeus
Nous avons une configuration similaire dans un projet ici, et je pense que
est suffisant, vous n'avez pas besoin de le Qualificatif supplémentaire. Mais dans mon expérience, vous devez définir l'attribut Transactionnel, trop. Alors déposez le Transactionnel annotation sur la classe DAO et de commencer le marquage individuel des méthodes avec
et je crois que le tx:annotation-driven élément dans le contexte ne fonctionne pas avec de multiples contextes, trop.
Et, idéalement, l'ensemble appartient à la couche de service de toute façon, vous ne voulez pas que votre DAOs de décider ou d'sais même pas dans quel contexte de Persistance ils sont appelés à partir. Donc, si vous voulez avoir un ReadContactService:
et un WriteContactService:
et un DAO qui est pas au courant du contexte. Ensuite, vous avez besoin seulement de N classes d'entité et vous pouvez les réutiliser des méthodes DAO (même writeOnly finira par avoir à lire à partir de la base de données, faites-moi confiance).
J'ai essayé votre solution , il est toujours de me donner la même erreur. J'ai trouvé cette solution mais je ne suis pas en mesure de l'obtenir ( concernant la configuration de point de vue ) stackoverflow.com/questions/1961566/...
Eh bien, il aide dans le cas où vous souhaitez créer des opérations en combinant les DAOs, par exemple. Si le DAOs prendre soin de leurs transactions elles-mêmes, il faut trouver un moyen de l'amadouer en ne faisant que. La séparation de la couche transactionnelle à partir des données réelles de l'accès à résoudre ce problème. Et dans votre cas, avec deux bases de données probablement, vous allez avoir besoin pour mettre en œuvre une couche qui porte nombloc et de la valeur transactionnelle. Cette couche doit être mis en œuvre deux fois autant que je sache, et, par conséquent, doivent être fines.
OriginalL'auteur wallenborn