Я проверил в Google много часов без хороших результатов, поэтому я делюсь своим кодом. Если у вас есть лучшее решение, я очень доволен!Мгновенное создание EntityManager из Datasource с свойствами JBoss
Проблема заключается в том:
Я добавил источник данных JPA в конфигурации JBoss и я добавил некоторые свойства
<datasource jta="false" jndi-name="java:/jdbc/MyApp" pool-name="MyApp_main" enabled="true" use-ccm="false">
<connection-url>jdbc:h2:mem:test;INIT=CREATE SCHEMA IF NOT EXISTS test</connection-url>
<driver-class>org.h2.Driver</driver-class>
<connection-property name="hibernate.hbm2ddl.auto">
create-drop
</connection-property>
<connection-property name="hibernate.show_sql">
true
</connection-property>
<driver>h2</driver>
<validation>
<validate-on-match>false</validate-on-match>
<background-validation>false</background-validation>
</validation>
<timeout>
<set-tx-query-timeout>false</set-tx-query-timeout>
<blocking-timeout-millis>0</blocking-timeout-millis>
<idle-timeout-minutes>0</idle-timeout-minutes>
<query-timeout>0</query-timeout>
<use-try-lock>0</use-try-lock>
<allocation-retry>0</allocation-retry>
<allocation-retry-wait-millis>0</allocation-retry-wait-millis>
</timeout>
<statement>
<share-prepared-statements>false</share-prepared-statements>
</statement>
</datasource>
Мой persistence.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="mainDatabase"
transaction-type="RESOURCE_LOCAL">
<jta-data-source>java:/jdbc/MyApp</jta-data-source>
<class>org.company.app.business.class1</class>
<class>org.company.app.business.class2</class>
<class>org.company.app.business.class3</class>
<properties>
<!-- Scan for annotated classes and Hibernate mapping XML files -->
<property name="hibernate.archive.autodetection" value="class, hbm" />
</properties>
</persistence-unit>
</persistence>
И мой код для введения в действие EntityManager:
Persistence.createEntityManagerFactory("mainDatabase");
Проблема заключается в том, что свойства hibernate.hbm2ddl.auto
и hibernate.show_sql
не были добавлены к EntityManager. Но эти свойства существуют на источник данных, когда я получить его с
final Context lInitCtx = new InitialContext();
final Object lEnvCtx = lInitCtx.lookup(lJNDIName);
final DataSource lWrapperDataSource = (DataSource) lEnvCtx;
Так что мое решение:
Я получаю имя JNDI из EntityManager:
EntityManagerFactory lEntityManagerFactory = Persistence.createEntityManagerFactory("mainDatabase");
final Map<String, Object> lConnectionProperties = lResult.getProperties();
// Extract JNDI name
final String lJNDIName = (String) lConnectionProperties.get("hibernate.connection.datasource");
I 've get datasource with
final Context lInitCtx = new InitialContext();
final Object lEnvCtx = lInitCtx.lookup(lJNDIName);
final DataSource lWrapperDataSource = (DataSource) lEnvCtx;
Я извлек свойства из этого источника данных. Это самое плохой код решения:
final Connection lConnection = lWrapperDataSource.getConnection();
final Field lField = lWrapperDataSource.getClass().getDeclaredField("mcf");
lField.setAccessible(true);
final Object lMCF = lField.get(lWrapperDataSource);
final Field lConnectionProps = lMCF.getClass().getDeclaredField("connectionProps");
lConnectionProps.setAccessible(true);
final Properties lProperties = (Properties) lConnectionProps.get(lMCF);
Я скопировал эти свойства в карту
final Map<String, String> lPersistenceProperties = new HashMap<>();
for (final Entry<Object, Object> lEntry : lProperties.entrySet()) {
final String lKey = (String) lEntry.getKey();
final String lValue = (String) lEntry.getValue();
lPersistenceProperties.put(lKey, lValue);
}
и я заново создать EntityManager с тезисами свойствами
lEntityManagerFactory = Persistence.createEntityManagerFactory("mainDatabase", lPersistenceProperties);
Опять же: если у вас есть лучшее решение, я очень рад не использовать рефлексию и получить частный член, используйте Context, ....
Я потерял - почему вы не добавляете эти два свойства вашей persistence.xml? Вы уже объявляете одно свойство hibernate (автоопределение), просто добавьте эти два. – Gimby
Я хочу дать возможность использовать базу данных Oracle или H2. И в мою компанию, если мы используем Oracle, мы должны экпортировать скрипты для создания/эволюции базы данных. Но если это h2-память, я должен сделать это напрямую с помощью моего веб-приложения. – Chklang
Я использовал для этого две разные единицы персистентности. – Gimby