0

I have a working JSF application with JPA. The JTA-DataSource is wildfly-managed.

Now I have to run some database operations periodically. As mentioned here ( SO: How to run a background task in a servlet based web application? ) I created the two classes:

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

The best whould be to access the registered Persistence Unit. I tried to get the EM via @PersistenceContext(unitName = "PU"), tried to register the Persistence in the web.xml to get it via JNDI, but had no luck.

Where is my mistake?

xentity
  • 117
  • 1
  • 1
  • 9
  • is this runnable a separate entity from web application ? Are you getting null ? If your Runnable is not MANAGED by container, you will not get container managed entitymanager there – Prasad Kharkar Aug 19 '16 at 09:47
  • @PrasadKharkar The two classes are part of the war archive. If I try to inject via PersistenceContext, the em is null. – xentity Aug 19 '16 at 09:55
  • You will get null because that class is not being managed by your container. Also, I am not able to understand the purpose of TestRunner. – Prasad Kharkar Aug 19 '16 at 10:15
  • The TestRunners method run() is called by Scheduler in the giving interval. The TestRunner it self is just a simplified test if em is available. edit: would it be more clever to use an EJB and the @schedule annotation for my purposes? – xentity Aug 19 '16 at 10:35

1 Answers1

0

Found a solution for me: define a second persistence content.

First, my persistence unit:

<?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 I use the EntityManager within the CDI-Beans via

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

Within the CronJob/Scheduler/Runnable I create the EntityManager via

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

So can I use the Persistence Context both in a container managed class and in unmanaged classes.

xentity
  • 117
  • 1
  • 1
  • 9