2016-08-19 4 views
0

Ich habe eine funktionierende JSF-Anwendung mit JPA. Die JTA-DataSource ist wildfly-verwaltet.Zugriff auf registrierte EntityManager in einer ausführbaren

Jetzt muss ich einige Datenbankoperationen regelmäßig ausführen. Wie hier erwähnt (SO: How to run a background task in a servlet based web application?) habe ich die beiden Klassen:

@WebListener 
public class Scheduler implements ServletContextListener { 

    private ScheduledExecutorService scheduler; 

    @SuppressWarnings("deprecation") 
    @Override 
    public void contextInitialized(ServletContextEvent event) { 
     Calendar c = new GregorianCalendar(); 
     Date d = c.getTime(); 
     int stm = 60 - d.getSeconds(); 
     int mth = 60 - d.getMinutes(); 

     scheduler = Executors.newSingleThreadScheduledExecutor(); 
     scheduler.scheduleAtFixedRate(new TestRunner(), stm, 60, TimeUnit.SECONDS); 
    } 

    @Override 
    public void contextDestroyed(ServletContextEvent event) { 
     scheduler.shutdownNow(); 
    } 
} 

public class TestRunner implements Runnable { 
    private EntityManager em; 

    public TestRunner() { 
    } 

    @Override 
    public void run() { 
     this.Test(); 
    } 

    public void Test() { 
     System.out.println("Test executed..."); 
     if (this.em != null) { 
      System.out.println(em.find(Ship.class, 2).getName()); 
      System.out.println(em.find(Commodity.class, 1).getName()); 
     } else { 
      System.out.println("EntityManager is null"); 
     } 
    } 
} 

Die besten die registrierte Persistenzeinheit sein whould zuzugreifen. Ich habe versucht, die EM über @PersistenceContext(unitName = "PU") zu bekommen, versucht, die Persistence in der web.xml zu registrieren, um es über JNDI zu bekommen, hatte aber kein Glück.

Wo ist mein Fehler?

+0

ist dies eine separate Entität von Web-Anwendung ausgeführt werden? Werden Sie null? Wenn Ihr Runnable nicht vom Container MANAGED verwaltet wird, erhalten Sie dort keinen Container-verwalteten Entitymanager –

+0

@PrasadKharkar Die beiden Klassen sind Teil des Kriegsarchivs. Wenn ich versuche, über PersistenceContext zu injizieren, ist das em null. – xentity

+0

Sie erhalten null, weil diese Klasse nicht von Ihrem Container verwaltet wird. Außerdem kann ich den Zweck von TestRunner nicht verstehen. –

Antwort

0

Eine Lösung für mich gefunden: Definieren Sie einen zweiten Persistenz-Inhalt.

Zuerst meine Persistenzeinheit:

<?xml version="1.0" encoding="UTF-8"?> 
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" 
    version="2.1"> 
    <persistence-unit name="PU" transaction-type="JTA"> 
     <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider> 
     <jta-data-source>java:jboss/datasources/mysqldb</jta-data-source> 
     <class>model.Commodity</class> 
     <class>...</class> 
     <properties> 
      <!-- <property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.JBossAppServerJtaPlatform"/> --> 
      <!-- <property name="hibernate.hbm2ddl.auto" value="update" /> --> 
      <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" /> 
      <!-- <property name="hibernate.show_sql" value="true" /> --> 
      <property name="hibernate.enable_lazy_load_no_trans" value="true" /> 
     </properties> 
    </persistence-unit> 

    <persistence-unit name="RLPU" transaction-type="RESOURCE_LOCAL"> 
     <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider> 
     <jta-data-source>java:jboss/datasources/mysqldb</jta-data-source> 
     <class>model.Commodity</class> 
     <class>...</class> 
     <properties> 
      <!-- <property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.JBossAppServerJtaPlatform"/> --> 
      <!-- <property name="hibernate.hbm2ddl.auto" value="update" /> --> 
      <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" /> 
      <!-- <property name="hibernate.show_sql" value="true" /> --> 
      <property name="hibernate.enable_lazy_load_no_trans" value="true" /> 
     </properties> 
    </persistence-unit> 

</persistence> 

In JSF verwende ich die EntityManager innerhalb der CDI-Beans über

@PersistenceContext(unitName = "PU", type = PersistenceContextType.EXTENDED) 
private EntityManager em; 

Im CronJob/Scheduler/Runnable erstelle ich den EntityManager über

public TestRunner() { 
    this.em = Persistence.createEntityManagerFactory("RLPU").createEntityManager(); 
} 

So kann ich den Persistence Context sowohl in einer Container-verwalteten Klasse und in nicht verwaltete Klassen.

Verwandte Themen