EntityManager em.getTransaction().begin() locks thread - java

My question is, if the method "begin()" is capable of lock a thread further than the "timeout" config in the persistence.xml.
Here is a snippet:
#Inject EntityManager em;
#Inject ContextControl ctxCtrl;
String fileType;
String fileName;
String hash;
BufferedReader reader = null;
public void run(File f, String fileType, String hash) throws ProcessorException, IOException{
this.fileType = fileType;
this.hash= hash;
this.fileName = f.getName();
try {
ctxCtrl.startContext(RequestScoped.class);
em.getTransaction().begin();
reader = openReader(f);
//rest of the code...
em.getTransaction().commit();
}catch (Exception e) {
logger.error(e.getMessage(), e);
try{ //for database breakdown purpose
em.getTransaction().rollback();
}catch(Exception e2){
logger.error(e2.getMessage(), e2);
throw new ProcessorException();
}
throw new ProcessorException();
}finally{
reader.close();
ctxCtrl.stopContext(RequestScoped.class);
}
"run" method is executed inside a loop. This method is executed serially, there is no possible concurrency.
Now, the thing is that the thread stops randomly at line "em.getTransaction().begin();", with no exception. And since this is a critical area, all the application is stopped and the lock is never released.
The only thing I can think of is the "begin()" method getting stuck somehow, but not in an exception way, but rather in a lock way (since no exception is caught).
I wasn't able to recreate the issue, I can only say that the issue has nothing to do with the file. Also, this is happening in production, so I can't debug the application other than check some logs
thanks in advance
EDIT
I use Deltaspike to provide the CDI. Entitymanager it's injected anytime it's needed. It's created like this:
CLASS ENTITYMANAGER FACTORY PRODUCER
import java.io.FileInputStream;
import java.util.Properties;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.inject.Disposes;
import javax.enterprise.inject.Produces;
import javax.inject.Inject;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import org.slf4j.Logger;
#ApplicationScoped
public class EntityManagerFactoryProducer {
#Inject Logger logger;
#Produces
#ApplicationScoped
public EntityManagerFactory create() {
Properties props = new Properties();
try {
props.load(new FileInputStream("cfg/connection.properties"));
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
return Persistence.createEntityManagerFactory("scgach",props);
}
public void destroy(#Disposes EntityManagerFactory factory) {
factory.close();
}
}
CLASS ENTITYMANAGER PRODUCER
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.inject.Disposes;
import javax.enterprise.inject.Produces;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
#ApplicationScoped
public class EntityManagerProducer {
#Inject EntityManagerFactory emf;
#Produces #RequestScoped
public EntityManager create() {
return emf.createEntityManager();
}
public void destroy(#Disposes EntityManager em) {
if(em.isOpen())
em.close();
}
}

Related

AttributeNotFoundException through JMX in Startup bean on Wildfly

Hello everyone!
I'm trying to load wildfly server's system properties through JMX in Startup bean's #PostConstruct method. It works fine on the already started server instance when deployment starts, but fails while starting with server instance bootstrapping.
Wildfly 11.0.0.CR1
Startup bean code:
package ru.wildfly.test.ejb.wildflyconsulregistrar.startup;
import ru.wildfly.test.ejb.wildflyconsulregistrar.api.ConsulRegistrar;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.ejb.Singleton;
import javax.ejb.Startup;
import javax.inject.Inject;
#Startup
#Singleton
public class WildflyConsulRegistrarStartupBean {
#Inject
private ConsulRegistrar consulRegistrar;
#PostConstruct
public void initialize() {
registerServices();
}
private void registerServices() {
consulRegistrar.registerService("WildflyTestCluster");
}
.............
}
ConsulRegistrar code:
package ru.wildfly.test.ejb.wildflyconsulregistrar.impl;
import com.ecwid.consul.v1.ConsulClient;
import com.ecwid.consul.v1.agent.model.NewService;
import ru.test.ejb.wildflyconsulregistrar.api.ConsulRegistrar;
import ru.wildfly.test.ejb.wildflyconsulregistrar.serversettings.api.CurrentServerNodeSettings;
import javax.annotation.PostConstruct;
import javax.enterprise.context.Dependent;
import javax.inject.Inject;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
#Dependent
public class ConsulRegistrarImpl implements ConsulRegistrar {
...............
#Inject
private CurrentServerNodeSettings currentServerNodeSettings;
.............
#Override
public void registerService(String serviceName) {
String currentNodeName = currentServerNodeSettings.getCurrentNodeName();
........................
}
.......................
}
CurrentServerNodeSettings code:
package ru.wildfly.test.ejb.wildflyconsulregistrar.serversettings.impl;
import ru.wildfly.test.ejb.wildflyconsulregistrar.serversettings.api.CurrentServerNodeSettings;
import javax.enterprise.context.Dependent;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import java.lang.management.ManagementFactory;
#Dependent
public class CurrentServerNodeSettingsWildflyImpl implements CurrentServerNodeSettings {
....................
#Override
public String getCurrentNodeName() {
String currentNodeName = getPlatformMBeanServerAttributeValue(String.class, "jboss.as:system-property=server.name", "value");
return currentNodeName;
}
private <T> T getPlatformMBeanServerAttributeValue(Class<T> valueType, String objectName, String attributeName) {
T attributeValue = null;
try {
MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
Object attributeObject = mBeanServer.getAttribute(new ObjectName(objectName), attributeName);
attributeValue = attributeObject != null ? (valueType.cast(attributeObject)) : null;
} catch (Exception ex) {
throw new IllegalStateException(ex);
}
return attributeValue;
}
}
Error message:
Caused by: java.lang.IllegalStateException:
javax.management.AttributeNotFoundException:
"WFLYCTL0216: Management resource '[(\"system-property\" => \"server.name\")]' not found"
at ru.wildfly.test.ejb.wildflyconsulregistrar.serversettings.impl.CurrentServerNodeSettingsWildflyImpl
.getPlatformMBeanServerAttributeValue(CurrentServerNodeSettingsWildflyImpl.java:41)
I have found the same issue on jboss forum https://developer.jboss.org/message/971717#971717 , but it was unanswered.
Any suggestions?
This is a dependency problem during startup, i.e. the server name is set after your #PostConstruct method gets executed. Try to load the server name lazy when it is accessed from the application for the first time.
In Wildfly there is no generic way to enforce the sequence of deployments from the application despite the definition of module dependencies. But this won't help in your case.

Java Dependency issue, not working for hibernate

Hello I am trying to follow this tutorial ::http://www.tutorialspoint.com/hibernate/hibernate_annotations.htm
my code in caseyou want to have a dig is here:
https://github.com/ArthurGibbs/Centaurus-
Im using restx framework.
I am trying to use hibernate to access a local database. however when i try compile my code i get a dependency error:
src/main/java/centaurus/service/UserDao.java:7: error: package org.hibernate does not exist
import org.hibernate.HibernateException;
but i have included it in my pom so i dont understand why I am getting the error.
this is my class where there error points to
package centaurus.service;
import centaurus.entity.GameUser;
import restx.factory.Component;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.SessionFactory;
#Component
public class UserDao {
private static SessionFactory factory;
public static void main(String[] args) {
try{
factory = new AnnotationConfiguration().
configure().
//addPackage("com.xyz") //add package if used.
addAnnotatedClass(GameUser.class).
buildSessionFactory();
}catch (Throwable ex) {
System.err.println("Failed to create sessionFactory object." + ex);
throw new ExceptionInInitializerError(ex);
}
UserDao ME = new UserDao();
}
/* Method to CREATE an employee in the database */
public Integer addEmployee(String email){
Session session = factory.openSession();
Transaction tx = null;
Integer employeeID = null;
try{
tx = session.beginTransaction();
GameUser employee = new GameUser();
employee.setEmail(email);
employeeID = (Integer) session.save(employee);
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
return employeeID;
}
public void saveId() {
addEmployee("bob");
}
}
new to hibernate, and not very experienced with maven. please help or let me know how to help you help me. thanks in advance
as I am using restx, it does not read the pom, it reads the md.restx.json file where i was missing the dependencies dependancies

NameAlreadyBoundException using JNDI

I created a session bean with this code:
package ejb2;
import javax.annotation.Resource;
import javax.ejb.SessionContext;
import javax.ejb.Stateless;
#Stateless(name = "TestEJB", mappedName = "EJB2-Project1-TestEJB")
public class TestEJBBean implements TestEJB, TestEJBLocal {
#Resource
SessionContext sessionContext;
public TestEJBBean() {
}
public String getHello(String who_welcome) {
return "Hello " + who_welcome;
}
}
As you can see, it's almost a default code (except getHello method). Besides this bean I have a client:
package ejb2;
import java.util.Hashtable;
import javax.naming.CommunicationException;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
public class TestEJBClient {
public static void main(String[] args) {
try {
final Context context = getInitialContext();
TestEJB testEJB = (TestEJB) context.lookup("EJB2-Project1-TestEJB#ejb2.TestEJB");
System.out.println(testEJB.getHello("Student"));
} catch (CommunicationException ex) {
System.out.println(ex.getClass().getName());
System.out.println(ex.getRootCause().getLocalizedMessage());
System.out.println("\n*** A CommunicationException was raised. This typically\n*** occurs when the target WebLogic server is not running.\n");
} catch (Exception ex) {
ex.printStackTrace();
}
}
private static Context getInitialContext() throws NamingException {
Hashtable env = new Hashtable();
// WebLogic Server 10.x/12.x connection details
env.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
env.put(Context.PROVIDER_URL, "t3://localhost:7101");
return new InitialContext(env);
}
}
First time it worked like a charm. But then I created another bean:
package ejb2;
import javax.annotation.Resource;
import javax.ejb.Stateless;
import javax.ejb.SessionContext;
import javax.naming.Context;
import javax.naming.InitialContext;
#Stateless(name = "ClientEJB", mappedName = "EJB2-Project1-ClientEJB")
public class ClientEJBBean implements ClientEJB, ClientEJBLocal {
#Resource
SessionContext sessionContext;
TestEJB testEJB;
public ClientEJBBean() {
try {
final Context context = new InitialContext();
testEJB = (TestEJB) context.lookup("EJB2-Project1-TestEJB#ejb2.TestEJB");
} catch (Exception ex) {
ex.printStackTrace();
}
}
public String getHelloFromBean(String who) {
return testEJB.getHello(who);
}
}
And now beans aren't working. I get an error like this:
weblogic.application.ModuleException: Unable to bind Business Interface to the JNDI name: EJB2Project1WebApp_warClientEJB_Home, throw exception javax.naming.NameAlreadyBoundException: [EJB:011224]Unable to bind the interface ejb2.ClientEJB to ClientEJB. Another EJB has already bound an interface to that name.; remaining name 'EJB2-Project1-ClientEJB#ejb2'. NestedException Message is :[EJB:011224]Unable to bind the interface ejb2.ClientEJB to ClientEJB. Another EJB has already bound an interface to that name.
What's the problem with these codes?
As far as i can see you try to deploy two stateless EJBs with the same JNDI name
Try to undeploy the current application , check the JNDI tree from Admin Console
and make sure the tree does not have the JNDI name you see as duplicate.

The attribute value is undefined for the annotation type Produces for "MediaType.APPLICATION_JSON"

I am getting a weird warning (while hovering the red line in eclipse) for this very simple restful service code:
(Eclipse draws a red line under "MediaType.APPLICATION_JSON")
import java.util.List;
import java.util.logging.Logger;
import javax.enterprise.inject.Produces;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import com.myCompany.annotation.RestfulServiceAddress;
import com.myCompany.myProject.middleware.api.myService;
#RestfulServiceAddress("/myCompany-middleware")
public class myServiceImpl implements myService {
private EntityManagerFactory entityManagerFactory;
#GET
#Path("/getStuff")
#Produces(MediaType.APPLICATION_JSON)
public List<Object> getStuff() {
EntityManager entityManager = entityManagerFactory
.createEntityManager();
try {
return entityManager.createQuery(
"Select S from Stuff S", Object.class)
.getResultList();
} catch (Exception ex) {
ex.printStackTrace();
return null;
} finally {
entityManager.close();
}
}
public EntityManagerFactory getEntityManagerFactory() {
return entityManagerFactory;
}
public void setEntityManagerFactory(
EntityManagerFactory entityManagerFactory) {
this.entityManagerFactory = entityManagerFactory;
}
}
Also maven builds the jar file without problems. But I get an error from the OSGI container, telling me the jar is failed.
Use #javax.ws.rs.Produces instead of javax.enterprise.inject.Produces
import javax.ws.rs.Produces;
// import javax.enterprise.inject.Produces;

Why does not commit transaction of Requires_New?

I am working on SAP java application server with EJB 3.0
I want to database insert one by one. Because I have too much data and I have to divide data. So I made try test code and it did work but it did not work as I want.
I want to create a new transaction for each part and of course at the end method(transaction) should be commit.
Sample code is below;
package com.transaction.jobs;
import javax.ejb.Local;
/**
*
* #author muratdemir
*/
#Local
public interface TestTransactionLocal {
public void onStart();
public void insertObject(int i);
}
and
package com.transaction.jobs;
import com.transaction.service.DatabaseServiceLocal;
import com.transaction.entity.Item;
import com.transaction.entity.Logger;
import java.util.Date;
import javax.annotation.Resource;
import javax.ejb.EJB;
import javax.ejb.EJBContext;
import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionManagementType;
/**
*
* #author muratdemir
*/
#Stateless
#TransactionManagement(TransactionManagementType.CONTAINER)
public class TestTransactionService implements TestTransactionLocal {
#EJB
DatabaseServiceLocal databaseService;
#Resource
EJBContext context;
#TransactionAttribute(TransactionAttributeType.REQUIRED)
public void onStart() {
try {
System.out.println("START");
Logger log1 = new Logger(new Date(), ">>>T1 commiting");
databaseService.create(log1);
System.out.println(">>>T1 committing");
Thread.sleep(5000);
for (int i = 1; i < 10; i++) {
System.out.println("Call new Transaction");
insertObject(i);
Thread.sleep(2000);
}
Thread.sleep(5000);
Logger log2 = new Logger(new Date(), "<<<T1 commiting");
databaseService.create(log2);
System.out.println("<<<T1 committing");
Thread.sleep(5000);
System.out.println("END");
} catch (Exception e) {
e.printStackTrace();
context.setRollbackOnly();
}
}
#TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public void insertObject(int i) {
try {
System.out.println("New Transaction Start i:" + i);
Item item = new Item(new Date(), "Name_" + i);
databaseService.create(item);
System.out.println("commit transaction: " + i);
} catch (Exception e) {
e.printStackTrace();
context.setRollbackOnly();
}
}
}
The insertObject(Requires_New) function is work but it did not commit. It waiting for commit other onStart(REQUIRED) function. If mytimer function is end, the insert function makes all commit.
Why new transaction is did not committed?
Note: If I change transaction attribute of the onStart function REQUIRED to NOT_SUPPORTED it works as I want. Why it works this way?
You have to initialize another TestTransactionLocal with a use of SessionContext#getBusinessObject method. This way your TestTransactionLocal instance will respect #TransactionAttribute annotation.
#Resource
private SessionContext sessionContext;
private TestTransactionLocal local;
#PostConstruct
void init() {
local = sessionContext.getBusinessObject(TestTransactionLocal.class);
}
Then invoke insertObject() through this new reference:
local.insertObject(i);
See this blog post: http://www.adam-bien.com/roller/abien/entry/how_to_self_invoke_ejb
You're calling prepare() method directly, so the transaction annotation isn't considered. You would need to call it through its own interface i.e. myTestTimerLocal.prepare(), for any transactional effect.

Categories

Resources