Соединение с базой данных во время выполнения JPA2

Я использую JP2 в своем текущем веб-проекте. Моя основная база данных содержит основные сущности. Чтобы подключиться к этой базе данных, я определил Persitance Unit с источником данных JTA:

Постоянство.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
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE resources PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Resource Definitions//EN" "http://glassfish.org/dtds/glassfish-resources_1_5.dtd">
<resources>
    <jdbc-connection-pool allow-non-component-callers="false" associate-with-thread="false" connection-creation-retry-attempts="0" connection-creation-retry-interval-in-seconds="10" connection-leak-reclaim="false" connection-leak-timeout-in-seconds="0" connection-validation-method="auto-commit" datasource-classname="org.postgresql.ds.PGSimpleDataSource" fail-all-connections="false" idle-timeout-in-seconds="300" is-connection-validation-required="false" is-isolation-level-guaranteed="true" lazy-connection-association="false" lazy-connection-enlistment="false" match-connections="false" max-connection-usage-count="0" max-pool-size="32" max-wait-time-in-millis="60000" name="post-gre-sql_mydb_mypool" non-transactional-connections="false" pool-resize-quantity="2" res-type="javax.sql.DataSource" statement-timeout-in-seconds="-1" steady-pool-size="8" validate-atmost-once-period-in-seconds="0" wrap-jdbc-objects="false">
        <property name="serverName" value="localhost"/>
        <property name="portNumber" value="5432"/>
        <property name="databaseName" value="mydb"/>
        <property name="User" value="myuser"/>
        <property name="Password" value="mypass"/>
        <property name="URL" value="jdbc:postgresql://localhost:5432/mydb"/>
        <property name="driverClass" value="org.postgresql.Driver"/>
        <property name="characterEncoding" value="UTF-8" />
    </jdbc-connection-pool>
    <jdbc-resource enabled="true" jndi-name="MyDB" object-type="user" pool-name="post-gre-sql_mydb_mypoll"/>
</resources>
0.xsd"> <persistence-unit name="MyPU" transaction-type="JTA"> <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> <jta-data-source>MyDB</jta-data-source> <exclude-unlisted-classes>false</exclude-unlisted-classes> <properties> <property name="eclipselink.logging.level" value="FINE"/> <property name="eclipselink.logging.parameters" value="true"/> <property name="eclipselink.logging.logger" value="ServerLogger"/> <property name="eclipselink.ddl-generation" value="drop-and-create-tables"/> </properties> </persistence-unit> </persistence>

и источник данных JTA, определенный в файле sun-resources.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE resources PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Resource Definitions//EN" "http://glassfish.org/dtds/glassfish-resources_1_5.dtd">
<resources>
    <jdbc-connection-pool allow-non-component-callers="false" associate-with-thread="false" connection-creation-retry-attempts="0" connection-creation-retry-interval-in-seconds="10" connection-leak-reclaim="false" connection-leak-timeout-in-seconds="0" connection-validation-method="auto-commit" datasource-classname="org.postgresql.ds.PGSimpleDataSource" fail-all-connections="false" idle-timeout-in-seconds="300" is-connection-validation-required="false" is-isolation-level-guaranteed="true" lazy-connection-association="false" lazy-connection-enlistment="false" match-connections="false" max-connection-usage-count="0" max-pool-size="32" max-wait-time-in-millis="60000" name="post-gre-sql_mydb_mypool" non-transactional-connections="false" pool-resize-quantity="2" res-type="javax.sql.DataSource" statement-timeout-in-seconds="-1" steady-pool-size="8" validate-atmost-once-period-in-seconds="0" wrap-jdbc-objects="false">
        <property name="serverName" value="localhost"/>
        <property name="portNumber" value="5432"/>
        <property name="databaseName" value="mydb"/>
        <property name="User" value="myuser"/>
        <property name="Password" value="mypass"/>
        <property name="URL" value="jdbc:postgresql://localhost:5432/mydb"/>
        <property name="driverClass" value="org.postgresql.Driver"/>
        <property name="characterEncoding" value="UTF-8" />
    </jdbc-connection-pool>
    <jdbc-resource enabled="true" jndi-name="MyDB" object-type="user" pool-name="post-gre-sql_mydb_mypoll"/>
</resources>

И вот как я получаю доступ к базе данных в своих классах DAO (ведьма — это @ManagedBeans и @SessionScoped):

@ManagedBean(name = "pageDao")
@SessionScoped
public class PageDao implements Serializable {

    @Resource
    private UserTransaction utx = null;

    @PersistenceUnit(unitName = "MyPU")
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public List<PageEnt> getAll() { ... }

    public PageEnt getOne(long pageId) { ... }

    public void addPage(PageEnt newPage) throws RollbackFailureException, PreexistingEntityException, Exception { ... }

    public PageEnt update(PageEnt page) throws RollbackFailureException, NonexistentEntityException, Exception { ... }

    public void remove(PageEnt page) throws RollbackFailureException, Exception { ... }
}

Одна из сущностей (клиент) имеет свойства для подключения к отдельной (клиентской) базе данных, которые определяются во время выполнения. Эти свойства включают в себя:

  • Имя базы данных
  • Хост и порт
  • Пользователь и пароль

Мой вопрос:

  • Как эффективно создать соединение с базой данных во время выполнения?
  • Как я могу создать новый EntityManager из ресурсов, управляемых контейнером, если для каждого клиента не определены PersistanceUnit и источники данных (ведьмы определяются во время развертывания)?
  • Если мне приходится вручную иметь дело с EntityManagerFactory (ведьма, как я узнал в колледже, является тяжелым и обширным объектом), как мне это сделать эффективно? Есть ли хорошая практика или шаблон?
  • Как будет работать шаблон DAO? Как мой класс DAO получит EntityManager?

Большое спасибо из Бразилии.


person Pedro Peixoto    schedule 25.06.2012    source источник


Ответы (1)


Во время выполнения можно переключаться между несколькими источниками данных. Он предоставляется Spring Источник абстрактных данных маршрутизации . Требуется переопределить метод #determineCurrentLookupKey(), который будет возвращать ключ для определения конкретного источника данных, который необходимо подключить. Также должна быть конфигурация spring, которая сопоставляет каждый из возможных ключей и соответствующие источники данных, которые необходимо подключить. Что-то вроде
<jee:jndi-lookup id="DataSource_Client1" jndi-name="DataSource_Client1" /> <jee:jndi-lookup id="DataSource_Client2" jndi-name="DataSource_Client" />
<bean id="DynamicDataSource" class="concrete implementation class name of AbstractRoutingDataSource">
<property name="targetDataSources">
<map key-type="java.lang.String">
<entry key="Client1" value-ref="DataSource_Client1" />
<entry key="Client2" value-ref="DataSource_Client2" />
</map>
</property>
</bean>

Возможная ссылка на этот источник динамических данных

Надеюсь, это ответ на один из ваших вопросов

person firefox784    schedule 29.06.2012