Getting access to registred EntityManager in a Runnable - java

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?

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.

Related

How to correctly inject EntityManager into JAX-WS web service?

I'm trying to implement a JAX-WS web service which has an endpoint that returns data from the configured data source. I managed to create the service and the client, but I can't access the database because I get Null Pointer Exceptions when I try to use the injected EntityManager.
Here is my service:
#WebService(serviceName="ViewDocuments")
public class ViewDocumentService {
#PersistenceContext(unitName = "HibernateJPA")
private EntityManager em;
#WebMethod
public String sayHello() {
return "Hello world!";
}
#Produces("application/json")
#WebMethod(operationName="getDocuments")
public List<File> getDocuments(#WebParam(name = "name") String filename) {
if(filename == null)
return em.createQuery("FROM File").getResultList();
else return null;
}
}
And here is my WebServiceClient:
#WebServiceClient(name="ViewDocuments", wsdlLocation = "http://localhost:8080/lab8/ViewDocuments?wsdl")
public class ViewDocumentClient extends Service {
protected ViewDocumentClient(URL wsdlDocumentLocation, QName serviceName) {
super(wsdlDocumentLocation, serviceName);
}
#WebEndpoint(name = "DocumentPort")
public ViewDocumentService getDocumentPort() {
return new ViewDocumentService();
}
}
I am trying to call the function here:
public class MainDocumentClient {
public static void main(String[] args) throws Exception {
URL wsdlUrl = new URL("http://localhost:8080/lab8/ViewDocuments?wsdl");
QName serviceName = new QName("http://webservices/", "ViewDocuments");
ViewDocumentClient service = new ViewDocumentClient(wsdlUrl, serviceName);
ViewDocumentService viewDocumentService = service.getDocumentPort();
System.out.println(viewDocumentService.sayHello());
System.out.println(viewDocumentService.getDocuments(null));
}
}
This is my persistence.xml file content:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.2"
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_2.xsd">
<persistence-unit name="HibernateJPA" transaction-type="JTA">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<jta-data-source>java:/Postgres-Source8</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQL95Dialect" />
<property name="hibernate.hbm2ddl.auto" value="create-drop" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="true" />
<property name="hibernate.archive.autodetection" value="class, hbm" />
</properties>
</persistence-unit>
<persistence-unit name="HibernateJPAForTests" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="javax.persistence.jdbc.url" value="jdbc:postgresql://localhost:5432/lab8" />
<property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver" />
<property name="javax.persistence.jdbc.user" value="postgres" />
<property name="javax.persistence.jdbc.password" value="<password>" />
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQL95Dialect" />
<property name="hibernate.hbm2ddl.auto" value="create-drop" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="true" />
<property name="hibernate.archive.autodetection" value="class, hbm" />
</properties>
</persistence-unit>
</persistence>
The sayHello() method works fine. I also tried to use an EntityManagerFactory, to instantiate my Repository by hand, to add the #Stateless annotation, but nothing seems to work. I just can't query my database.
After lots of research, I still can't seem to understand how to properly inject the EntityManager. Can someone explain this to me, please?
I am using Wildfly21.0.0.

Apache Karaf, can't inject entity manager

I want to use entity manager from container, but when I try to access it I get
java.lang.IllegalStateException: Need active coordination
persistence.xml
<persistence-unit name="data-point" transaction-type="JTA">
<jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=dvdrental)</jta-data-source>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQL82Dialect"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.hbm2ddl.auto" value="update"/>
<property name="hibernate.connection.driver_class" value="org.postgresql.Driver"/>
<property name="hibernate.archive.autodetection" value="class"/>
</properties>
bluprint.xml
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 https://osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd"
default-activation="eager"
xmlns:tx="http://aries.apache.org/xmlns/transactions/v1.2.0"
xmlns:jpa="http://aries.apache.org/xmlns/jpa/v2.0.0">
<jpa:enable />
<tx:enable-annotations />
<service id="filesEntityManager" ref="filesEntityManagerImpl" interface="ru.bia.karaf.dao.FilesEntityManager"/>
<bean id="filesEntityManagerImpl" class="ru.bia.karaf.dao.FilesEntityManagerImpl"/>
<bean id="testBean" class="ru.bia.karaf.web.TestBean" init-method="test">
<property name="filesEntityManager" ref="filesEntityManagerImpl"/>
</bean>
TestBean.java
public class TestBean {
private FilesEntityManagerImpl filesEntityManager;
public void test(){
System.out.println("hey bro from init");
System.out.println("filesEntityManager = " + filesEntityManager);
System.out.println("filesEntityManager.getEm() = " + filesEntityManager.getEm());
}
public FilesEntityManagerImpl getFilesEntityManager() {
return filesEntityManager;
}
public void setFilesEntityManager(FilesEntityManagerImpl filesEntityManager) {
this.filesEntityManager = filesEntityManager;
}
}
FilesEntityManagerImpl.java
#OsgiServiceProvider(classes = {FilesEntityManager.class})
#Transactional
public class FilesEntityManagerImpl implements FilesEntityManager {
#PersistenceContext(unitName="data-point")
EntityManager em;
...
}
The EntityManager that is injected into FilesEntityManagerImpl is a thread local proxy of the EntityManager. Its lifecycle is bound to a Coordination.
If you access em outside of a Coordination you get this error. You can make sure a Coordination is active by using the #Transactional annotations. If you
do not need an actual transaction but only the Coordination then use #Transactional(TxType.SUPPORTS).
You should also generally not access the EntityManager outside of the object that is injected with it.

Provider org.hibernate.envers.event.EnversIntegrator not a subtype error in CDI+JPA2.1+Restful

I am trying to call JPA from a rest web service. but it throws me
org.hibernate.integrator.spi.Integrator: Provider org.hibernate.envers.event.EnversIntegrator not a subtype at org.apache.cxf.service.invoker.AbstractInvoker.createFault(AbstractInvoker.java:170) at
org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:136) at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:204) at
org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:101) at
org.apache.openejb.server.cxf.rs.AutoJAXRSInvoker.invoke(AutoJAXRSInvoker.java:68) at org.apache.cxf.interceptor.ServiceInvokerInterceptor
I have used maven 4, JPA 2.1, CDI.
My code:
JPA part:
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("defaultMainUnit", null);
EntityManager entityManager = entityManagerFactory.createEntityManager();
Persistence.generateSchema("defaultMainUnit", null);
Query master Query = entityManager
.createNamedQuery("master.findAll");
List<Master > masterList = masterQuery.getResultList();
for(Master master : masterList){
System.out.println("Master id: "+master .getMaster TrackingId());
}
entityManager.clear();
entityManager.close();
persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence 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"
version="2.1">
<persistence-unit name="defaultMainUnit" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>core.Master</class>
<class>core.Child</class>
<properties>
<property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver" />
<property name="hibernate.connection.url" value="jdbc:hsqldb:mem:defaultDB" />
<property name="hibernate.connection.username" value="sa" />
<property name="hibernate.connection.password" value="" />
<property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect" />
<property name="hibernate.show_sql" value="false" />
<property name="hibernate.hbm2ddl.auto" value="create-drop" />
<property name="hibernate.connection.release_mode" value="after_statement"/>
<!-- insert data using sql file -->
<property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/>
<property name="javax.persistence.schema-generation.create-source" value="metadata"/>
<property name="javax.persistence.schema-generation.drop-source" value="metadata"/>
<property name="javax.persistence.sql-load-script-source" value="mcb-test-import.sql"/>
</properties>
</persistence-unit>
Restservice:
package restcdi.rest;
#Path("/")
public class GreetREST {
#Inject
private EnglishGreet greet;
#GET
#Path("/greet")
#Produces(MediaType.TEXT_PLAIN)
public String greet() {
return greet.greet();
}
#GET
#Path("/master")
#Produces(MediaType.APPLICATION_JSON)
public List master() throws FileNotFoundException, IOException{
CheckJPAProperties check = new CheckJPAProperties();
List masterList = check.runMe();
return masterList;
}
}
in the above code, runMe() returns all the masters in database using JPA code above. when i run the JPA code without a rest service in main it runs fine and returns everything. I am not sure what I am missing. I tried including the hibernate-envers dependency in pom.xml but it still throws the same error.
please help.
ps: just in case this is needed i am including my applicationConfig
package restcdi.rest;
import java.util.Set;
import javax.ws.rs.core.Application;
#javax.ws.rs.ApplicationPath("rest")
public class ApplicationConfig extends Application {
#Override
public Set<Class<?>> getClasses() {
Set<Class<?>> resources = new java.util.HashSet<>();
resources.add(GreetREST.class);
return resources;
}
}

JPA entries are not created or retrieved

I'm having program that creates JPA entries with the entity manager.
during the process I don't get any errors.
...
factory = Persistence.createEntityManagerFactory("perst");
EntityManager entityManager = factory.createEntityManager();
entityManager.getTransaction().begin();
entityManager.persist(object);
entityManager.getTransaction().commit();
...
entityManager.close();
I have created a program like follows to read the data but it doesn't return any data,
the query returns empty. What could be the reason ?
This is the program to read the data:
static List<String> classList = new ArrayList<String>();
private static EntityManagerFactory factory;
public static void main(String[] args) {
// TODO Auto-generated method stub
factory = Persistence.createEntityManagerFactory("perst");
EntityManager entityManager = factory.createEntityManager();
classList.add("LeaveRequest");
classList.add("person");
for (Object classOjc : classList) {
String className = classOjc.toString();
Query query = entityManager.createQuery("SELECT p FROM " + className + " p");
#SuppressWarnings("rawtypes")
List resultList = query.getResultList();
System.out.println(resultList.size());
for (Object result : resultList) {
System.out.println(result.toString());
}
}
}
the xml persist is:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.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_1_0.xsd">
<persistence-unit name="perst" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>LeaveRequest</class>
<class>person</class>
<properties>
<property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.EmbeddedDriver" />
<property name="javax.persistence.jdbc.url"
value="jdbc:derby:/home/vogella/databases/simpleDb;create=true" />
<property name="javax.persistence.jdbc.user" value="Sales" />
<property name="javax.persistence.jdbc.password" value="" />
<!-- EclipseLink should create the database schema automatically -->
<property name="eclipselink.ddl-generation" value="drop-and-create-tables" />
<property name="eclipselink.ddl-generation.output-mode"
value="database" />
<property name="eclipselink.logging.level" value="SEVERE" />
<property name="eclipselink.logging.exceptions" value="true" />
</properties>
</persistence-unit>
</persistence>
You configured eclipselink to drop and recreate the schema each time the app is started:
<property name="eclipselink.ddl-generation" value="drop-and-create-tables" />
So obviously, if you run a first application that persists some entries, and then a second application which tries to read what the first one has written, you won't find anything anymore, since eclipselink drops everything and recreates the schema every time.

how to call stored procedure with multiple in and out parameters using entity manager

We are facing an issue while calling the stored procedure from the application.
The database is oracle 10g
This proc has 2 input parameters and 2 output parameters.
Input 1:- DB-List
Input 2:- String
Output 1:-Again a DB-List
Output 2:- Number
When we are trying to use
Query q = session.createSQLQuery("{call proc_name(?,?,?,?)}");
We cannot distinguish between in parameters and out parameters.
So how should we handle it by using this.
Also,
We tried to use callable statement as follows:
Session session = (Session) getEntityManager().getDelegate();
SessionImpl sessionImpl = ((SessionImpl) getEntityManager().getDelegate());
Connection cc = sessionImpl.connection();
CallableStatement callableStatement = null;
callableStatement = cc.prepareCall("{call proc_name(?,?,?,?)}");
ArrayDescriptor descriptor = ArrayDescriptor.createDescriptor("DB_LIST",callableStatement.getConnection());
ARRAY paramArray = new ARRAY(descriptor, callableStatement.getConnection(), array);
callableStatement.setArray(1, paramArray);
callableStatement.setString(2, "N");
callableStatement.registerOutParameter(3, OracleTypes.ARRAY, "DB_RETURN_LIST");
callableStatement.registerOutParameter(4, Types.INTEGER);
// executing the query
callableStatement.execute();
We get the following error:
javax.ejb.EJBException: java.lang.ClassCastException:
$Proxy50 cannot be cast to oracle.jdbc.OracleConnection
Can you please provide some suggestions.
This is the Entity Manager that we are using
public abstract class GenericDAO<T, ID extends Serializable> implements IGenericDAO<T, ID> {
private final Class<T> persistentClass;
#PersistenceContext(unitName = "firstPersistenceUnit")
#Produces
private EntityManager entityManager;
public void setEntityManager(final EntityManager entityManager) throws DataAccessException {
this.entityManager = entityManager;
}
public EntityManager getEntityManager() throws DataAccessException {
return entityManager;
}
}
Here is the entry in the Persistance.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="firstPersistenceUnit">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>java:jboss/firstDataSource</jta-data-source>
<class>com.domain.Branch</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
<validation-mode>AUTO</validation-mode>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" />
<property name="hibernate.connection.driver_class" value="oracle.jdbc.driver.OracleDriver" />
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
</properties>
</persistence-unit>
<persistence-unit name="secondPersistenceUnit">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>java:jboss/secondDataSource</jta-data-source>
<class>com.domain.PocJeeCounty</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
<validation-mode>AUTO</validation-mode>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" />
<property name="hibernate.connection.driver_class" value="oracle.jdbc.driver.OracleDriver" />
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
</properties>
</persistence-unit>
</persistence>
Dont use second way, instead create and define query and query parameters using #NamedStoredProcedureQuery and #StoredProcedureParameter. Following is the code for your requirement
#NamedStoredProcedureQuery(
name="PROC_NAME",
procedureName="proc_name",
returnsResultSet=true/false,
parameters={
#StoredProcedureParameter(queryParameter="param1",name="p1",direction=Direction.IN,type=Integer.class),
#StoredProcedureParameter(queryParameter="param2",name="p2",direction=Direction.IN,type=Timestamp.class),
#StoredProcedureParameter(queryParameter="param3",name="p3",direction=Direction.OUT,type=String.class),
#StoredProcedureParameter(queryParameter="param4",name="p4",direction=Direction.OUT,type=Integer.class)
}
)
and use em.createNativeQuery() method

Categories