使用JBoss属性从Datasource实例化EntityManager

时间:2015-05-27 07:28:57

标签: java hibernate jpa jboss entitymanager

我已经在谷歌检查了很多小时没有取得好成绩,所以我分享了我的代码。 如果您有更好的解决方案,我非常感兴趣!

问题是:

我已将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.autohibernate.show_sql没有添加到EntityManager。但是当我用

获取它时,这些属性存在于数据源中
final Context lInitCtx = new InitialContext();
final Object lEnvCtx = lInitCtx.lookup(lJNDIName);
final DataSource lWrapperDataSource = (DataSource ) lEnvCtx;

所以我的解决方案是:

我从EntityManager获取了JNDI名称:

EntityManagerFactory lEntityManagerFactory = Persistence.createEntityManagerFactory("mainDatabase");
final Map<String, Object> lConnectionProperties = lResult.getProperties();

// Extract JNDI name
final String lJNDIName = (String ) lConnectionProperties.get("hibernate.connection.datasource");

我用它获取数据源

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,....

1 个答案:

答案 0 :(得分:0)

试试这段代码,我使用了Wildfly,JPA和jsf:

standalone.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>

的persistence.xml

@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;
    }

}

JPA实体:

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;
    }


}

JSF控制器:

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();
        }
       }

}

EmployeeBean.java

<!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>

JSF页面:

hookspath