How to remove stateless entity Java persistence - java

I have the following situation with Java persistence:
public ReturnCodes startWork() {
sessionBackup = (BaseService<Backup>) ctx.lookup("XYZ/BackupServiceImpl/local");
Backup backup = new Backup();
backup.setStatus(BackupStatus.EXECUTING);
....
sessionBackup.save(Backup) //at this point is not actualy saved into DB
....//try to connect somewhere
if ( !ConnectSuccess) {
sessionBackup.remove(backup);
return ReturnCodes.REQUESTABORT
}
....
}
#Stateless
public class BackupServiceImpl extends BaseServiceImpl<Backup> implements
BaseService<Backup>
{
#Override
protected Class<Backup> getEntityClass()
{
return Backup.class;
}
}
And the save and remove methods of BaseServiceImpl:
public abstract class BaseServiceImpl<T extends Serializable> implements
BaseService<T>
{
protected EntityManagerFactory emf;
public T save(T entity)
{
EntityManager em = emf.createEntityManager();
em.persist(entity);
return entity;
}
public void remove(T entity)
{
EntityManager em = emf.createEntityManager();
try
{
final Method method = getEntityClass().getMethod("getId");
final String id = (String) ((T) method.invoke(entity));
entity = em.find(getEntityClass(), id);
em.remove(entity);
}
catch (final Exception ex)
{
logger.log(Level.WARNING, "Unexpected error", ex);
}
}
}
I don't want to save into the DB in case ConnectSuccess fails, but the remove method fails to find the entity (because is not yet into the DB), and after returning ReturnCodes.REQUESTABORT the entity is saved.
How can I cancel the save?

In general in this case you do a setRollbackOnly().
You may also throw an exception which will trigger the rollbackonly.
See http://www.developerscrappad.com/547/java/java-ee/ejb3-x-jpa-when-to-use-rollback-and-setrollbackonly/
By the way doing this in your code:
catch (final Exception ex)
{
logger.log(Level.WARNING, "Unexpected error", ex);
}
is too broad and will block rollback functionality.

Related

Why do I cannot user createCriteria method which I define in ManagerBase class?

I dont know why i cannot call getAll() class in ManagerBase class from UserDAO, but with other class it still be ok
Hibernate code here
protected Session getCurrentSession() throws Exception {
if (session == null){ //check session null
if (sessionFactory == null){ //build sessionFactory if it null
if(sessionFactoryConfigPath == null || sessionFactoryConfigPath.equals("")){
sessionFactory = new Configuration().configure().buildSessionFactory();
}else{
sessionFactory = new Configuration().configure(this.sessionFactoryConfigPath).buildSessionFactory();
}
}
session = sessionFactory.getCurrentSession();
}
return session;
}
ManagerBase code
public abstract class ManagerBase<T> extends HibernateUtil {
private Class<T> persistentClass;
public ManagerBase() throws Exception {
super();
this.persistentClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments().getClass();
}
public ManagerBase(String sessionFactoryConfigPath) throws Exception {
super(sessionFactoryConfigPath);
this.persistentClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments().getClass();
}
public Class<T> getPersistentClass() {
return this.persistentClass;
}
public List<T> getAll() {
List<T> list = null;
try {
beginTransaction();
list = getCurrentSession().createCriteria(this.persistentClass).list();
commitAndClose();
} catch (Exception ex) {
System.out.println("getAll Error \n" + ex);
}
return list;
}
UserDAO code here.....
code
public class UserDAO extends ManagerBase<User> {
public UserDAO() throws Exception {
}
public List<User> getAllUser() {
try {
List<User> user = getAll();
return user;
} catch (Exception ex) {
System.out.println("Get All User Error \n" + ex);
return null;
}
}
}
Any body please help me, in the console board that show only Begin and commit and it doesnt has any HQL code.

How to make DAO thread safe JPA?

I am new to JPA and Java. I understood how EntityManager and EMF works a littel bit. I have JPAUtill from where I get EntityManager, which is using ThreadLocal variable, which makes EntityManager thread safe. I have DAO where in I am persisting new users when having 10 thousand thread accesses simultaneously.
I get to see following exception:
javax.persistence.PersistenceException: org.hibernate.SessionException: Session is closed!
at org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:614)
Here is my DAO code
try{
entityManager = JPAUtil.getEntityManager();
user.setArea(getArea());
user.setCity(getCity());
user.setPassword("xxxxx");
user.setEmail_Id(getEmail_Id());
user.setMobile_Num(TempMobile_Num);
user.setFirst_Name(getFirst_Name());
user.setSession_Id("0");
user.setEmail_Verification_Status("NOT VERIFIED");
user.setBalance(new BigDecimal(0.00));
if (!entityManager.getTransaction().isActive()){
entityManager.getTransaction().begin();
}
entityManager.persist(user);
JPAUtil.commit();
} catch (Exception e) {
logger.info(e);
e.printStackTrace();
} finally{
if(entityManager.isOpen())
JPAUtil.closeEntityManager();
}
JPAUtil:
public class JPAUtil {
private static Logger logger = Logger.getLogger(JPAUtil.class);
private static EntityManager entityManager = null;
private static final ThreadLocal<EntityManager> threadLocal;
private static EntityManagerFactory emf = null;
static {
try {
emf = Persistence.createEntityManagerFactory("XYZDB");
threadLocal = new ThreadLocal<EntityManager>();
} catch (Throwable ex) {
logger.info("JPAUtil Exception", ex);
throw new ExceptionInInitializerError(ex);
}
}
public static EntityManager getEntityManager() {
try {
entityManager = threadLocal.get();
if (entityManager == null || !entityManager.isOpen()) {
JPAUtil.entityManager = emf.createEntityManager();
threadLocal.set(entityManager);
} else if (!emf.isOpen()) {
entityManager = threadLocal.get();
emf = Persistence.createEntityManagerFactory("XYZDB");
JPAUtil.entityManager = emf.createEntityManager();
threadLocal.set(entityManager);
}
} catch (Throwable ex) {
logger.info("JPAUtil Exception", ex);
throw new ExceptionInInitializerError(ex);
}
return JPAUtil.entityManager;
}
public static void closeEntityManager() {
EntityManager entityManager = threadLocal.get();
if (entityManager != null) {
entityManager.close();
threadLocal.set(null);
}
}
public static void closeEntityManagerFactory() {
emf.close();
}
public static void commit() {
if (!entityManager.getTransaction().isActive()) {
entityManager.getTransaction().begin();
}
entityManager.getTransaction().commit();
}
public static void rollback() {
if (!entityManager.getTransaction().isActive()) {
entityManager.getTransaction().begin();
}
entityManager.getTransaction().rollback();
}
}
Can someone please help me understand the issue and how to resolve it?
Remove this static variable form JPAUtil:
private static EntityManager entityManager = null;
You were still using a static variable; you didn't really use the ThreadLocal.
Change your getEntityManager to this:
public static EntityManager getEntityManager() {
EntityManager entityManager;
try {
entityManager = threadLocal.get();
if (entityManager == null || !entityManager.isOpen()) {
entityManager = emf.createEntityManager();
threadLocal.set(entityManager);
}
} catch (Throwable ex) {
logger.info("JPAUtil Exception", ex);
throw new ExceptionInInitializerError(ex);
}
return entityManager;
}

EntityManager.close() Not Closing The Connections to Database Tomcat

Here is my JPA Utill Class....
private static Logger logger=Logger.getLogger(JPAUtil.class);
private static EntityManager entityManager = null;
private static final ThreadLocal<EntityManager> threadLocal;
private static EntityManagerFactory emf = null;
static
{
try {
emf = Persistence.createEntityManagerFactory("XYZ");
threadLocal = new ThreadLocal<EntityManager>();
} catch (Throwable ex) {
logger.info("JPAUtil Exception",ex);
throw new ExceptionInInitializerError(ex);
}
}
public static EntityManager getEntityManager() {
try {
entityManager = threadLocal.get();
if (entityManager == null || !entityManager.isOpen()) {
JPAUtil.entityManager = emf.createEntityManager();
threadLocal.set(entityManager);
}else if(!emf.isOpen())
{
entityManager = threadLocal.get();
emf = Persistence.createEntityManagerFactory("XYZ");
JPAUtil.entityManager = emf.createEntityManager();
threadLocal.set(entityManager);
}
} catch (Throwable ex) {
logger.info("JPAUtil Exception",ex);
throw new ExceptionInInitializerError(ex);
}
return JPAUtil.entityManager;
}
public static void closeEntityManager() {
EntityManager entityManager = threadLocal.get();
if (entityManager != null) {
entityManager.close();
threadLocal.set(null);
}
}
public static void closeEntityManagerFactory() {
emf.close();
}
public static void commit() {
if (!entityManager.getTransaction().isActive()){
entityManager.getTransaction().begin();
}
entityManager.getTransaction().commit();
}
public static void rollback() {
if (!entityManager.getTransaction().isActive()){
entityManager.getTransaction().begin();
}
entityManager.getTransaction().rollback();
}
And After each and every transactions i am closing entitymanager....with
finally block...and later i came to Know that even in select query we need to
begin transaction and commit it...so i did try that in my application Home
page Just executing 2 select query and in the server mysql is Occupying the memory the most....with the eclipse MAT i Anallise the Memory Leak....
As per my understanding since i am using tomcat i cant do connection pooling..and we will be moving to jboss...but till the i would like to patch this....any help would be appreciated :) :)

Lost transaction with JPA unique constraint?

I have a field with an unique constraint:
#Column(unique=true)
private String uriTitle;
When I try to save two entities with the same value, I get an exception - but another exception than I exected:
java.lang.IllegalStateException: <|Exception Description: No transaction is currently active
at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.rollback(EntityTransactionImpl.java:122)
at com.example.persistence.TransactionFilter.doFilter(TransactionFilter.java:35)
The questionable filter method looks like this:
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain)
throws IOException, ServletException {
EntityManager entityManager = ThreadLocalEntityManager.get();
EntityTransaction transaction = entityManager.getTransaction();
transaction.begin();
try {
chain.doFilter(request, response);
transaction.commit();
}
catch (Throwable t) {
transaction.rollback(); // line 35, mentioned in the exception
throw new RuntimeException(t);
}
finally {
entityManager.close();
ThreadLocalEntityManager.reset();
}
}
... and the ThreadLocalEntityManager like this:
public class ThreadLocalEntityManager {
private static EntityManagerFactory entityManagerFactory = null;
private static final ThreadLocal<EntityManager> entityManager =
new ThreadLocal<EntityManager>() {
#Override
protected EntityManager initialValue() {
return entityManagerFactory.createEntityManager();
}
};
private ThreadLocalEntityManager() {}
public static synchronized void init(String persistenceUnit) {
requireNotNull(persistenceUnit);
requireState(entityManagerFactory == null, "'init' can be called only "
+ "once.");
entityManagerFactory =
Persistence.createEntityManagerFactory(persistenceUnit);
}
public static EntityManager get() {
requireState(entityManagerFactory != null, "Call 'init' before calling "
+ "'get'");
return entityManager.get();
}
public static void reset() {
entityManager.remove();
}
}
I wrapped the call to save with try ...catch to handle the unique constraint violation, but that doesn't work:
try {
ThreadLocalEntityManager.get().persist(article); // article is constrained
}
catch(Throwable t) {
t.printStackTrace();
}
Any idea why there is no transaction? What is the correct way to handle a unique constraint violation?
Your transaction rolled back automatically due to DB constraint violation, therefore there is no transaction to rollback manually. To handle this case, you can write
catch (Throwable t) {
if (transaction.isActive())
transaction.rollback(); // line 35, mentioned in the exception
throw new RuntimeException(t);
}
You don't have any separation between transactions and GUI in your application. You will have problems with transaction handling in general.

Adding a persistence unit in JNDI for EJB modules

I am working on a simple EJB module using sample code. I am trying to implement CURD operations through a SOAP web service. I have a persistence unit defined in persistence.xml.
Here is the code for my implementation. The problem is that I cannot create an instance of PersistenceService because the persistence unit name is not present in the JNDI listings.
If, instead of using code injection, I use
EntityManagerFactory emf = Persistence.createEntityManagerFactory(PU_NAME);
em = emf.createEntityManager();
the code runs, but then the transaction is managed by the container. I was reading through some tutorials and they mentioned that, in this scenario, if the user wants to roll the transaction back later, he cannot do so.
What can I do instead?
users class
#WebService()
#Stateless()
public class users {
public users()
{
}
/**
* Web service operation
*/
#WebMethod(operationName = "addUser")
public Integer addUser(
#WebParam(name = "UserName") final String UserName,
#WebParam(name = "LastName") final String LastName) {
DatabaseEntityManager dem = new DatabaseEntityManager();
Integer result = null;
try
{
result = dem.addUser(UserName, LastName, false);
dem.commitTx();
return result;
} catch(Exception E)
{
}
return new Integer(-1);
}
DatabaseEntityManager class
public class DatabaseEntityManager {
PersistenceService ps_bck = null;
public DatabaseEntityManager()
{
}
public SiteUsers addUser(
String Username,
String LastName, boolean commit) throws Exception
{
AppUser appUser = new appUser(UserName, LastName);
//AppUser is an entity class
PersistenceService ps = PersistenceService.getInstance();
try
{
ps.beginTx();
EntityManager em = ps.getEntityManager();
em.persist(appUser);
if (commit)
ps.commitTx();
else
ps_bck = ps;
}
catch (Exception E)
{
ps.rollbackTx();
}
finally
{
ps.close();
}
return appUser.getId();
}
void commitTx() throws Exception
{
try
{
ps_bck.commitTx();
}
catch(Exception E)
{
throw E;
}
finally
{
ps_bck =null;
}
}
}
PersistenceService class — borrowed from sample code generated by NetBeans
public class PersistenceService {
private static String DEFAULT_PU = "pers-ejbPU";
private static ThreadLocal<PersistenceService> instance = new ThreadLocal<PersistenceService>() {
#Override
protected PersistenceService initialValue() {
return new PersistenceService();
}
};
private EntityManager em;
private UserTransaction utx;
private PersistenceService() {
try {
//This code runs
// EntityManagerFactory emf = ersistence.createEntityManagerFactory(DEFAULT_PU);
// em = emf.createEntityManager();
//This code throws an exception
this.em = (EntityManager) new InitialContext().lookup("java:comp/env/persistence/"+ DEFAULT_PU);
this.utx = (UserTransaction) new InitialContext().lookup("java:comp/UserTransaction");
} catch (NamingException ex) {
throw new RuntimeException(ex);
}
}
/**
* Returns an instance of PersistenceService.
*
* #return an instance of PersistenceService
*/
public static PersistenceService getInstance() {
return instance.get();
}
private static void removeInstance() {
instance.remove();
}
/**
* Returns an instance of EntityManager.
*
* #return an instance of EntityManager
*/
public EntityManager getEntityManager() {
return em;
}
/**
* Begins a resource transaction.
*/
public void beginTx() {
try {
utx.begin();
em.joinTransaction();
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
/**
* Commits a resource transaction.
*/
public void commitTx() {
try {
utx.commit();
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
/**
* Rolls back a resource transaction.
*/
public void rollbackTx() {
try {
utx.rollback();
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
/**
* Closes this instance.
*/
public void close() {
removeInstance();
}
}
If your persistence.xml has an entry
<persistence-unit name="PU_NAME" transaction-type="JTA">
In your PersistenceService class, add the annotation:
#PersistenceContext (name = "PU_NAME") private EntityManager em;

Categories