Hibernate EntityManager not managed by wildfly - java

I'm trying to add hibernate to old project that is currently using plain SQLs + SeesionContext/DataSource classes. My problem is that I can't force Wildfly (version 21) to manage EntityManager. Persistence.createEntityManagerFactory("customJpa").createEntityManager(); is working correctly, persistence.xml file is read correctly.
I've tried to inject #PersistenceUnit for EntityManagerFactory, add hibernate annotations repo etc. but without any success. I'm basically stuck after trying every possible solution I've found in documentation or here.
I'm probably doing some silly mistake, but I can't figure that out.
persistence.xml file is located under src\main\resources\META-INF\persistence.xml, in WAR - deployments\project.war\WEB-INF\classes\META-INF\persistence.xml.
build.gradle:
implementation([
...
'org.hibernate:hibernate-core:5.6.3.Final',
'com.oracle.ojdbc:ojdbc8:19.3.0.0'
])
Persistence.xml file looks like:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<persistence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd"
version="2.2">
<persistence-unit name="customJpa" transaction-type="JTA">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<jta-data-source>java:/jdbc/customDS</jta-data-source>
<class>com.entities.Entity</class>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="hibernate.hbm2ddl.auto" value="update"/>
<property name="hibernate.implicit_naming_strategy" value="org.hibernate.boot.model.naming.ImplicitNamingStrategyJpaCompliantImpl"/>
<property name="hibernate.search.default.worker.backend" value="jms"/>
<property name="hibernate.search.default.worker.jms.connection_factory" value="java:/ConnectionFactory"/>
<property name="hibernate.search.default.directory_provider" value="filesystem"/>
<!-- Uncomment only for debugging -->
<!--<property name="hibernate.show_sql" value="true"/>-->
<!--<property name="hibernate.format_sql" value="true"/>-->
</properties>
</persistence-unit>
</persistence>
DB settings file:
<?xml version="1.0" encoding="UTF-8"?>
<datasources>
<xa-datasource jndi-name="java:/jdbc/customDS" pool-name="pollXADS">
<xa-datasource-class>...</xa-datasource-class>
<xa-datasource-property name="URL">...</xa-datasource-property>
<driver>ojdbc7.jar</driver>
<security>
<user-name>...</user-name>
<password>...</password>
</security>
<validation>
<valid-connection-checker class-name="org.jboss.jca.adapters.jdbc.extensions.oracle.OracleValidConnectionChecker"/>
<stale-connection-checker class-name="org.jboss.jca.adapters.jdbc.extensions.oracle.OracleStaleConnectionChecker"/>
<exception-sorter class-name="org.jboss.jca.adapters.jdbc.extensions.oracle.OracleExceptionSorter"/>
</validation>
<xa-pool>
<min-pool-size>0</min-pool-size>
<max-pool-size>30</max-pool-size>
<is-same-rm-override>false</is-same-rm-override>
</xa-pool>
<timeout>
<blocking-timeout-millis>10000</blocking-timeout-millis>
<idle-timeout-minutes>10</idle-timeout-minutes>
</timeout>
</xa-datasource>
</datasources>
Java base repo class:
#Stateless
#TransactionAttribute(TransactionAttributeType.REQUIRED)
public abstract class BaseRepositoryImpl<Entity, Id> implements BaseRepository<Entity, Id>
{
private final Class<Entity> clazz;
#PersistenceContext(unitName = "customJpa")
private final EntityManager em;
protected BaseRepositoryDAO(Class<Entity> clazz)
{
this.clazz = clazz;
this.em = getEntityManager();
}
...
//Workaroud - creating entityManager using Persistence class is working
protected EntityManager getEntityManager()
{
if (em != null)
{
return em;
}
return Persistence.createEntityManagerFactory("customJpa").createEntityManager();
}

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.

JBoss 7 & EJB3 | Where should I define datasource

I'm new to Jboss and I don't understand where should I define the database connection data like url, username, password etc..
Here is my multimodule project:
app-root
app-api
- src
- pom.xml
app-ear
- src
- pom.xml
app-ejb
- src
- pom.xml
pom.xml
My persinstence.xml located unter app-root/app-ejb/src/main/config/default/META-INF/persistence.xml
<?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="ejb3_jpa_myapp_pu" transaction-type="JTA">
<description>Jboss Test application</description>
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>java:jdbc/MyApp</jta-data-source>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect" />
<property name="hibernate.hbm2ddl.auto" value="none" />
<property name="hibernate.show_sql" value="true" />
</properties>
</persistence-unit>
</persistence>
And finaly my simple Service:
#Stateless
#Remote(IService.class)
public class ServiceImpl implements IService{
#PersistenceContext(unitName = "ejb3_jpa_myapp_pu")
private EntityManager em;
#Override
public void doSomeJob() {
// [...]
}
}
I know I have to define the database connection properties but where can I do that?
You need to define the data source in the standalone XML file that your JBoss instance is using. JBoss does not ship with database drivers so there are two steps:
1) Create a JBoss module for the database drivers (eg MySQL, Oracle, Postgres etc)
2) Create the datasource definition
Step 1) needs only to be done once, ie many MySQL datasources can use the same MySQL JBoss module.
Step 2) An example datasource configuration for MySQL would be:
<datasources>
<datasource jndi-name="java:jboss/datasources/MySqlDS" pool-name="MySqlDS">
<connection-url>jdbc:mysql://localhost:3306/EJB3</connection-url>
<driver>com.mysql</driver>
<transaction-isolation>TRANSACTION_READ_COMMITTED</transaction-isolation>
<pool>
<min-pool-size>10</min-pool-size>
<max-pool-size>100</max-pool-size>
<prefill>true</prefill>
</pool>
<security>
<user-name>test</user-name>
<password>test</password>
</security>
<statement>
<prepared-statement-cache-size>32</prepared-statement-cache-size>
<share-prepared-statements/>
</statement>
</datasource>
<drivers>
<driver name="com.mysql" module="com.mysql">
<xa-datasource-class>com.mysql.jdbc.jdbc2.optional.MysqlXADataSource</xa-datasource-class>
</driver>
</drivers>
</datasources>
The above can be automated using the JBoss CLI. Also creating the JBoss modules can also be automated for example using the smartics-jboss-modules-maven-plugin see Generate an xml file with all dependencies with maven for more info.

JBoss EAP 6.3 CMT Multiple persistence units

This is essentially a duplicate of How to locate the source of JBAS011470 error in JBoss?
But essentially, As soon as I add a second persistence unit, it gives me this error. It's ridiculous. I'm not going to disable the JPA subsystem like some people suggest - that sounds wrong.
My persistence.xml setup is as follows, where java:/NAME is set up as a datasource in standalone.xml:
<?xml version="1.0"?>
<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="name" transaction-type="JTA">
<jta-data-source>java:/NAME</jta-data-source>
<class>za.co.classes.A</class>
<class>za.co.classes.B</class>
<class>za.co.classes.C</class>
<properties>
<property name="hibernate.transaction.jta.platform"
value="org.hibernate.service.jta.platform.internal.JBossAppServerJtaPlatform"/>
<property name="hibernate.transaction.manager_lookup_class"
value="org.hibernate.transaction.JBossTransactionManagerLookup"/>
<property name="jboss.entity.manager.factory.jndi.name"
value="java:jboss/persistence/NAME" />
<property name="jboss.entity.manager.jndi.name"
value="java:jboss/persistence/em/NAME" />
<property name="hibernate.dialect" value="za.co.equrahealth.dao.SQLServerDialect" />
</properties>
</persistence-unit>
The error starts as soon as I add a second persistence unit. So spring context is irrelevant.
Well, I luckily have multiple databases within the same schema, so I came up with a workaround. But it's obviously not going to solve the problem when there are multiple schemas. I think the cause of this issue might actually be a bug in JBoss.
#PersistenceContext
private EntityManager entityManager;
private EntityManager getEntityManager(String source)
{
if ("a".equalsIgnoreCase(source))
{
entityManager.createNativeQuery("USE A_DB;").executeUpdate();
}
else
{
entityManager.createNativeQuery("USE B_DB").executeUpdate();
}
return entityManager;
}

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.

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