Injecting EntityManager always null - java

I'm trying to inject an EntityManager into my application using CDI but the EntityManager is null when trying to use it.
Here is my code I followed several tutorial on how to inject EntityManager and I use the same code as in those tutorial.
#Qualifier
#Retention(RetentionPolicy.RUNTIME)
#Target({ElementType.FIELD})
public #interface DevDatabase {
}
#Singleton
public class JPAResourceProducer {
#Produces
#PersistenceContext(unitName = "DevPU")
#DevDatabase
private EntityManager em;
}
the persistence.xml
<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="DevPU" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>entity.MyEntity</class>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="javax.persistence.jdbc.url" value="jdbc:postgresql://localhost:5432/MyDB"/>
<property name="javax.persistence.jdbc.user" value="appuser"/>
<property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver"/>
<property name="javax.persistence.jdbc.password" value="apppassword"/>
</properties>
</persistence-unit>
</persistence>
This is how I use it in my DAO
public abstract class GenericDAO<T> {
#DevDatabase
#Inject
private EntityManager em;
private final Class<T> entityClass;
public GenericDAO(Class<T> entityClass) {
this.entityClass = entityClass;
}
public void beginTransaction() {
em.getTransaction().begin();
}
}
Concrete DAO
public class MyEntityDAO extends GenericDAO<MyEntity> {
public MyEntityDAO() {
super(MyEntity.class);
}
}
And somewhere in my code when I call for exemple myEntityDao.beginTransaction() I get a NullPointerException cause the injected EntityManager is null.
Is there anything I am missing in my producer ?

#PersistenceContext does not work out-of-the-box in a servlet container like tomcat. It works in a Java EE container.
So your EntityManager field stays to null because #PersistencContext has no effect in Tomcat, even using Weld-servlet.
You may add a ServletListener to bootstrap a JPA implementation, probalby hibernate in your case. Then you may obtain EntityManagerinstances through #Inject.
Note that you should also provide a JPA implementation (like hibernate), the same way you did for Weld.
You can try doing something like: Injecting EntityManager with a producer in tomcat

Related

Ejb wont initialize entity manager

my english is not my native language so i am sorry in advanced for my poor english.
My project is working well when i manage the transaction with entity manager, entity factory and get transactions.
I want to use the ejb to handle the transactions for me.
I did every thing needed in order for it to work but the ejb wont initalized the entity manager and he will stay null.
i cant understand what i am doing wrong.
i have configured my persistance.xml with jta data source and did all the annotations needed but still cant get it to work.
what i try to create a query i get a null pointer exception and the entity manager is null.
I have been searching and looking for a solution but did not succeed.
I hope some one here can find the answer.
Thank you for you time!
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="swap" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>java:jboss/datasources/swap</jta-data-source>
<class>org.Roper.WebService.Model.User</class>
<class>org.Roper.WebService.Model.BaseEntity</class>
<class>org.Roper.WebService.Model.Person</class>
<class>org.Roper.WebService.Model.Admin</class>
<class>org.Roper.WebService.Model.BusinessOwner</class>
<class>org.Roper.WebService.Model.Business</class>
<class>org.Roper.WebService.Model.Product</class>
<class>org.Roper.WebService.Model.Category</class>
<class>org.Roper.WebService.Model.Tourist</class>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<!-- Hibernate properties -->
<property name="javax.persistence.jdbc.driver"
value="org.postgresql.Driver" /> <!-- DB Driver -->
<property name="hibernate.hbm2ddl.auto" value="update" />
<property name="hibernate.connection.zeroDateTimeBehavior"
value="convertToNull" />
<property name="hibernate.show_sql" value="false" />
<property name="hibernate.format_sql" value="true" />
<property name="hibernate.dialect"
value="org.hibernate.dialect.PostgreSQLDialect" />
<property name="hibernate.transaction.jta.platform"
value="org.hibernate.service.jta.platform.internal.JBossStandAloneJtaPlatform" />
<!-- Database properties -->
<property name="javax.persistence.jdbc.url"
value="jdbc:postgresql://hidden/swap?useUnicode=yes&characterEncoding=UTF-8" /> <!-- BD Mane -->
<property name="javax.persistence.jdbc.user" value="hidden" /> <!-- DB User -->
<property name="javax.persistence.jdbc.password"
value="hidden" /> <!-- DB Password -->
</properties>
</persistence-unit>
</persistence>
This is the main class that call the ejb:
#Path("PersonService")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public class PersonResource {
private static final Logger logger = Logger.getLogger(PersonResource.class);
#EJB
PersonService personService = new PersonService();
#GET
#Path("/users")
public List<Person> getUsers(#BeanParam FilterBean fb)
{
logger.info("Getting all users.");
return personService.GetAllUsers();
}
}
this is the service class that call the entity managet:
#Stateless
#LocalBean
public class PersonService {
private static final Logger logger = Logger.getLogger(PersonService.class);
#PersistenceContext(unitName="swap")
public EntityManager em;
/**
*This function is querying the database selecting all the person entities.
*#return List of all the users from the database.
*/
public List<Person> GetAllUsers()
{
logger.debug("Starting to get all users.");
try {
try {
List<Person> users = em.createQuery("SELECT u FROM Person u").getResultList();
logger.info("Success, got all users.");
return new ArrayList<Person>(users);
}
catch(PersistenceException e)
{
if(e.getCause().getCause().getMessage().contains("ERROR: relation \"users\" does not exist"))
{
logger.info("No users in the database.");
}
else
{
logger.error("Error while getting users from the database, error: ", e);
}
}
}catch(Exception e)
{
logger.error("Cant get the users, error: ",e);
}
return null;
}
The datasource from the standalone-full.xml:
<subsystem xmlns="urn:jboss:domain:datasources:5.0">
<datasources>
<datasource jndi-name="java:jboss/datasources/swap" pool-name="swap" enabled="true" use-java-context="true">
<connection-url>jdbc:postgresql://127.0.0.1:5432/swap?useUnicode=yes&characterEncoding=UTF-8</connection-url>
<driver>org.postgresql</driver>
<security>
<user-name>postgres</user-name>
<password>postgres</password>
</security>
</datasource>
<drivers>
<driver name="org.postgresql" module="org.postgresql">
<driver-class>org.postgresql.Driver</driver-class>
<xa-datasource-class>org.postgresql.Driver</xa-datasource-class>
</driver>
</drivers>
</datasources>
</subsystem>
Following lines look suspicious:
#EJB
PersonService personService = new PersonService();
It should be either injected (so no = new PersonService();is needed) or created via constructor but that instance is not managed by any container and, as a consequence, no injection happens there and EntityManager em stays null.
Please update your code as follows:
#EJB
PersonService personService;
Beside that, Integrating JAX-RS with EJB Technology and CDI section of JavaEE 6 tutorial suggests that JAX-RS resources should be either EJBs themselves (so annotated with #Stateless or #Stateful) OR CDI beans (so annotated with #ApplicationScoped or #RequestScoped). I would suggest to add a #Stateless annotation on the PersonResource class itself.

A JTA EntityManager cannot use getTransaction() in stored procedure call

I want to do an asynchronous transactional action in a ejb method by calling a stored procedure. When I call the methot I give below error:
java.lang.IllegalStateException: A JTA EntityManager cannot use getTransaction()
Bean
#Stateless
public class FileSearchDAO {
private static Logger logger = LoggerFactory.getLogger(FileSearchDAO.class);
#PersistenceContext(unitName = "FileSearchPU")
private EntityManager entityManager;
#Asynchronous
public Future<String> saveFile(String fileNo, List<String> runningFiles) {
try {
entityManager.getTransaction().begin();
entityManager.createNativeQuery(
" BEGIN prc_save_file (:fileNo); END;")
.setParameter("fileNo", fileNo).executeUpdate();
entityManager.getTransaction().commit();
runningFiles.remove(fileNo);
return new AsyncResult<>(fileNo);
} catch (Exception ex) {
ex.printStackTrace();
return new AsyncResult<>(ex.getMessage());
}
}
persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
<persistence-unit name="FileSearchPU" transaction-type="JTA">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<jta-data-source>jdbc/FileSearchDS</jta-data-source>
<properties>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
<property name="hibernate.transaction.jta.platform"
value="${hibernate.transaction.jta.platform}"/>
</properties>
</persistence-unit>
</persistence>
I haven't any Entity class. I just want to call the stored procedure which updates some table.
In a JTA managed datasource container handles transactions in a distributed way so also handling concurrency outside your application for example.
EntityManagers transaction can not be used because it is local transaction so something that is then not handled outside your application. Read also this post for more information.
If you need transaction you should use UserTransaction
#Resource
UserTransaction utx;
To use it your annotate your bean
#TransactionManagement(TransactionManagementType.BEAN)
and use transaction like
utx.begin();
...
utx.commit(); // utx.rollback();

Glassfish 4 - TransactionRequiredException using Hibernate and CDI #Transactional

I am getting the following exception:
javax.el.ELException: javax.persistence.TransactionRequiredException
at com.sun.el.parser.AstValue.invoke(AstValue.java:279)
at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:304)
at org.jboss.weld.util.el.ForwardingMethodExpression.invoke(ForwardingMethodExpression.java:40)
at org.jboss.weld.el.WeldMethodExpression.invoke(WeldMethodExpression.java:50)
Caused by: javax.persistence.TransactionRequiredException
at com.sun.enterprise.container.common.impl.EntityManagerWrapper.doTxRequiredCheck(EntityManagerWrapper.java:161)
at com.sun.enterprise.container.common.impl.EntityManagerWrapper.doTransactionScopedTxCheck(EntityManagerWrapper.java:151)
at com.sun.enterprise.container.common.impl.EntityManagerWrapper.persist(EntityManagerWrapper.java:299)
I am using Hibernate 4.3.5
#Named
#SessionScoped
public class MenuBean implements Serializable {
#PersistenceContext
private EntityManager entityManager;
#Transactional
public void create() {
MenuTitle menu = new MenuTitle();
menu.setLabel(label);
entityManager.persist(menu); //exception in this line
label = null;
}
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://www.oracle.com/webfolder/technetwork/jsc/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="MyPersistenceUnit" transaction-type="JTA">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<jta-data-source>MySQL5</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="hibernate.current_session_context_class" value="jta"/>
<property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.SunOneJtaPlatform"/>
<property name="hibernate.hbm2ddl.auto" value="none"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect"/>
</properties>
</persistence-unit>
I have also tried to set hibernate.transaction.jta.platform to org.hibernate.engine.transaction.jta.platform.internal.SunOneJtaPlatform but it results in the same error.
EJB CMT´s are working fine.
The Create action is called from a commandButton:
<p:commandButton value="Create" process="#this type" update=":megaMenuForm:mainMenu" actionListener="#{menuBean.create()}" oncomplete="closeMenuDialog(xhr, status, args)"/>
See EJB specs if you want to manage transaction. Inject a resource UserTransaction.
Also #Transactional with not do anything here since you are using EJB.
In general you example should work, and #Transactional annotation will be just ignored. Could you try to make an interface, and call create method through it?
Looks like you are using EJB 2 style coding, but Glassfish 4 implements EJB 3.1, so it is better to go with a new one.

Vaadin JPAContainer doesn't work

I created a web app application like my work thesis. This application used the entire stack java EE 6: JPA2, EJB, JSF, RichFaces....
Now i'm trying to change the UI of my application from RichFaces to Vaadin. The first problems began with use of JPA container. i can't get a instance of entitymanager.
this is my 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="primary">
<jta-data-source>java:jboss/VaadinDS</jta-data-source>
<class>org.mypackage.entity.Utente</class>
<class>org.mypackage.entity.Indirizzo</class>
<class>org.mypackage.entity.Paese</class>
<properties>
<!-- Properties for Hibernate -->
<property name="hibernate.hbm2ddl.auto" value="create" />
<property name="hibernate.show_sql" value="false" />
</properties>
</persistence-unit>
</persistence>
this is my singelton class where i want to get the i instance of entitymanager
public class Utility {
private static EntityManager entityManager;
public Utility() {
// TODO Auto-generated constructor stub
}
public static EntityManager getInstance(){
if(entityManager == null)
entityManager = JPAContainerFactory.createEntityManagerForPersistenceUnit("primary");
return entityManager;
}
}
but doesn't work , i showed always the followed error:
[com.vaadin.server.DefaultErrorHandler] (http-localhost-127.0.0.1-8080-1) : java.lang.NullPointerException
where i wrong?
Your persistence.xml file needs to have a dialect property
Also, you need 2 other things that the book of vaadin explain if you are using hibernate with the jpacontainer: The use of one entity manager per reqeust pattern and the use of hibernate lazy loading delegate on your entity provider. If you need more help, I'll keep updating this answer.

How to update entity in JPA

This is my first real exposure to JPA and I'm trying to run the simplest of update statements. I'm running inside a jBoss 7.1.x server using Hibernate as JPA implementation. Any help would be greatly appreciated..
Here is my producer method for EntityManager:
#ApplicationScoped
public class EntityManagerProducer
{
#PersistenceContext
private EntityManager entityManager;
#Produces
#RequestScoped
public EntityManager getEntityManager()
{
return entityManager;
}
}
Here is the DAO method that tries to perform the update:
#Inject EntityManager em;
public void updateRequestStatus(String requestNumber, String newStatus)
{
em.getTransaction().begin();
ServiceRequestEntity serviceRequestToUpdate = em.find(RequestEntity.class, requestNumber);
requestToUpdate.setStatus(newStatus);
em.merge(serviceRequestToUpdate);
em.getTransaction().commit();
}
Here is persistence.xml:
<?xml version="1.0" encoding="UTF-8"?>
<persistence 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"
version="2.0">
<persistence-unit name="database" transaction-type="RESOURCE_LOCAL">
<jta-data-source>java:/jdbc/myDS</jta-data-source>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="false" />
<property name="hibernate.use_sql_comments" value="true" />
</properties>
</persistence-unit>
</persistence>
Here is the error message (can provide full stacktrace if needed -it chokes on the "merge" line):
javax.persistence.TransactionRequiredException: JBAS011469: Transaction is required to perform this operation (either use a transaction or extended persistence context)
....
at org.jboss.weld.proxies.EntityManager$-1727851269$Proxy$_$$_WeldClientProxy.merge(EntityManager$-1727851269$Proxy$_$$_WeldClientProxy.java) [weld-core-1.1.5.AS71.Final.jar:]
#Inject annotation on EntityManager I don't think will work. With your current setup I believe you want to inject your EntityManagerProducer class (which is not used in your DAO), and then call your getEntityManager method on it.
The other option would just be to use the #PersistenceContext in your DAO.
You also may want to specify the name of your persistence context as specified in your persistence.xml like:
#PersistenceContext(name="database")

Categories

Resources