2015-05-27 1 views
0

Я проверил в 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, ....

+0

Я потерял - почему вы не добавляете эти два свойства вашей persistence.xml? Вы уже объявляете одно свойство hibernate (автоопределение), просто добавьте эти два. – Gimby

+0

Я хочу дать возможность использовать базу данных Oracle или H2. И в мою компанию, если мы используем Oracle, мы должны экпортировать скрипты для создания/эволюции базы данных. Но если это h2-память, я должен сделать это напрямую с помощью моего веб-приложения. – Chklang

+0

Я использовал для этого две разные единицы персистентности. – Gimby

ответ

0

попробуйте этот код, я использовал Wildfly, JPA и JSF:

standalone.xml:

<subsystem xmlns="urn:jboss:domain:datasources:2.0"> 
      <datasources> 
       <datasource jndi-name="java:jboss/datasources/employee" pool-name="MysqlDS2" enabled="true" use-java-context="true"> 
        <connection-url>jdbc:mysql://localhost:3306/employee</connection-url> 
        <driver>mysqld</driver> 
        <pool> 
         <min-pool-size>10</min-pool-size> 
         <max-pool-size>20</max-pool-size> 
         <prefill>true</prefill> 
        </pool> 
        <security> 
         <user-name>root</user-name> 
         <password>123456</password> 
        </security> 
       </datasource> 
       <drivers> 
        <driver name="mysqld" module="com.mysql"> 
         <driver-class>com.mysql.jdbc.Driver</driver-class> 
        </driver> 
       </drivers> 
      </datasources> 
     </subsystem> 

persistence.xml

<?xml version="1.0" encoding="UTF-8"?> 
<persistence version="2.1" 
    xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"> 
    <persistence-unit name="employee" transaction-type="JTA"> 
     <jta-data-source>java:jboss/datasources/employee</jta-data-source> 

     <class>model.Employee</class> 
    </persistence-unit> 
</persistence> 

JPA лицо:

@Entity 
@Table(name="employees") 
@NamedQuery(name="Employee.findAll", query="SELECT e FROM Employee e") 
public class Employee implements Serializable { 
    private static final long serialVersionUID = 1L; 

    @Id 
    private int id; 

    private String address; 

    private String name; 

    public Employee() { 
    } 

    public int getId() { 
     return this.id; 
    } 

    public void setId(int id) { 
     this.id = id; 
    } 

    public String getAddress() { 
     return this.address; 
    } 

    public void setAddress(String address) { 
     this.address = address; 
    } 

    public String getName() { 
     return this.name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

} 

JSF Контроллер:

package com.java.experts.controllers; 

import javax.ejb.EJB; 

import model.Employee; 
import beans.EmployeeBean; 

public class EmployeeController { 
    @EJB 
    EmployeeBean employeeBean; 
    Employee emp; 


    public EmployeeController() { 
     emp=new Employee(); 

     employeeBean=new EmployeeBean(); 
    } 

    public String add() 
    { 
     employeeBean.create(emp); 
     return ""; 
    } 

    public Employee getEmp() { 
     return emp; 
    } 

    public void setEmp(Employee emp) { 
     this.emp = emp; 
    } 


} 

EmployeeBean.Java

package beans; 

import inteceptors.MyInterceptor; 

import javax.ejb.Stateless; 
import javax.ejb.TransactionManagement; 
import javax.ejb.TransactionManagementType; 
import javax.interceptor.Interceptors; 
import javax.persistence.EntityManager; 
import javax.persistence.PersistenceContext; 

import model.Employee; 

@Stateless 
@TransactionManagement(TransactionManagementType.CONTAINER) // class level 
public class EmployeeBean { 
    @PersistenceContext(unitName="employee") 
     private EntityManager em; 

     public void create(Employee... gs) { 
      if(em==null) 
      { 
       System.out.println("entitymanager is null"); 
       return; 

      } 


      try { 
      for(Employee g : gs) { 
        em.persist(g); 
       } 
     } catch (Exception e) { 
      System.out.println("Error"); 
      e.printStackTrace(); 
     } 
     } 

} 

JSF Страница:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" 
    xmlns:ui="http://java.sun.com/jsf/facelets" 
    xmlns:h="http://java.sun.com/jsf/html" 
    xmlns:f="http://java.sun.com/jsf/core" 
    xmlns:p="http://primefaces.org/ui"> 
<h:head> 
</h:head> 
<h:body> 
    <h:form id="main" prependId="false"> 


     <table width="100%" border="0" cellpadding="3" cellspacing="0" 
      align="center" class="bodyTable"> 


      <tr> 
       <td> 
        <h:inputText value="#{employeeController.emp.name}"></h:inputText> 
       </td> 
      </tr> 
      <tr> 
       <td colspan="2"><label> <h:commandButton id="add" 
          action="#{employeeController.add}" value="Add Employee" /> 
       </label> <label></label></td> 
      </tr> 
     </table> 
    </h:form> 
</h:body> 
</html> 
+0

Я не вижу никаких 'connection-property' в вашем standalone.xml. Вы пытались добавить какое-либо свойство «connection-property», чтобы проверить, что эти свойства переопределяют persistence.xml? – Chklang

+0

Я создал соединение в standalone.xml и использовал его persistence.xml с помощью имени JNDI java: jboss/datasources/employee

+0

вся информация, необходимая для подключения к MySql DB, является там в standalone.xml –