You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@openjpa.apache.org by Phani Madgula <ph...@gmail.com> on 2008/12/30 08:26:33 UTC

Entities not flushing into oracle database.

Hi,

I am using Apache Geronimo for my JPA applications. I am using oracle
10G database for my entities.

I have an EAR application with an EJB and a WEB module. EJB module has
an SLSB that uses Container Managed Transactions and uses Container
Managed Persistence Manager (EntityManager injected by container). The
code is as follows.

************
package sample.jpa;


import javax.ejb.EJBException;
import javax.ejb.Remote;
import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceContextType;


@Stateless
@Remote(AccountInterface.class)
public class AccountBean implements AccountInterface {


    @PersistenceContext(type=PersistenceContextType.TRANSACTION)
    private EntityManager manager;


    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public Account open(int accountNumber) {
        Account account = manager.find(Account.class, accountNumber);
        if(account == null){
        	account = new Account();
        	account.ownerName = "anonymous";
            account.accountNumber = accountNumber;
            manager.persist(account);
            manager.flush();
            return account;
        }else{
        	throw new EJBException("Account already exists..!!. Account
Number = "+accountNumber);
        }

    }

    @TransactionAttribute(TransactionAttributeType.REQUIRED)
	public double getBalance(int accountNumber) {
    	 Account account = manager.find(Account.class, accountNumber);
        if(account==null)
            throw new EJBException("Account not found..!!. Account
Number = "+accountNumber);
        return account.balance;
    }

    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public void deposit(int accountNumber, double amount) {
    	Account account = manager.find(Account.class, accountNumber);
        if(account==null)
        	throw new EJBException("Account not found..!!. Account Number
= "+accountNumber);
        double new_balance = account.getBalance() + amount;
        account.setBalance(new_balance);
        manager.flush();
    }

    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public double withdraw(int accountNumber, double  amount) {
    	
    	Account account = manager.find(Account.class, accountNumber);
    	
        if(account==null)
        	throw new EJBException("Account not found..!!. Account Number
= "+accountNumber);

        if (amount > account.getBalance()) {
            return 0;
        } else {
        	double new_balance = account.getBalance() - amount;
            account.setBalance(new_balance);
            manager.flush();
            return amount;
        }
    }



}
**************

The Account.java is an entity.

The WEB module has a servlet that looks up EJB to perform amount
transfer from one account to another.

The code is as follows.

******************
package sample.jpa;

import java.io.IOException;
import java.io.PrintWriter;

import javax.ejb.EJB;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.transaction.UserTransaction;

/**
 * Servlet implementation class for Servlet: Test
 *
 */
 public class Test extends javax.servlet.http.HttpServlet implements
javax.servlet.Servlet {
   static final long serialVersionUID = 1L;


   @PersistenceContext(unitName="AccountUnit")
   private EntityManager em;

   @EJB AccountInterface accountBean;

    /* (non-Java-doc)
	 * @see javax.servlet.http.HttpServlet#HttpServlet()
	 */
	public Test() {
		super();
	}   	
	
	/* (non-Java-doc)
	 * @see javax.servlet.http.HttpServlet#doGet(HttpServletRequest
request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse
response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		PrintWriter out = response.getWriter();
		
		int accNo1 = Integer.parseInt(request.getParameter("account1"));
		int  accNo2 = Integer.parseInt(request.getParameter("account2"));
		double amount = Double.parseDouble(request.getParameter("amount"));
		
		try{
			Context ctx = new InitialContext();
			UserTransaction ut =
(UserTransaction)ctx.lookup("java:comp/UserTransaction");
			ut.begin();
			Account account = em.find(Account.class, accNo1);
			if(account.getBalance() < amount){
				throw new Exception("Account "+accNo1+" does not have enough
balance "+amount);
			}else{
				out.println("Account ="+accNo1+" : Current balance "+account.getBalance());
				accountBean.withdraw(accNo1, amount);
				out.println("Account ="+accNo1+" : Withdrawn "+amount);
				double balance = account.getBalance();
				out.println("Account ="+accNo1+" : After withdrawing the balance
is "+balance);
				Account account2 = em.find(Account.class, accNo2);
				out.println("Account ="+accNo2+" : Current balance "+account2.getBalance());
				accountBean.deposit(accNo2, amount);
				out.println("Account ="+accNo2+" : After depositing the balance is
"+account2.getBalance());
			}
			em.flush();
			ut.commit();
		}catch(Exception e){
			throw new ServletException(e);
		}
	}  	
	
	/* (non-Java-doc)
	 * @see javax.servlet.http.HttpServlet#doPost(HttpServletRequest
request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse
response) throws ServletException, IOException {
		// TODO Auto-generated method stub
	}   	  	
}
****************

The persistence.xml file is as follows.

******************
  <?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" version="1.0"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">

<persistence-unit name="AccountUnit" transaction-type="JTA">
  <description>ContainerManagedJPA</description>
  <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
  <jta-data-source>PhaniOraclePool</jta-data-source>
  <class>sample.jpa.Account</class>
  </persistence-unit>
</persistence>
***************

The "PhaniOraclePool" is the datasource deployed on the Geronimo
server over Oracle database.

Problems :
**********
1. When the servlet is executed, the committed values are not flushing
to Oracle database. After a transaction, when I query the database on
SQLPLUS prompt, I still get the old values. I have used all possible
methods like enititymanager.flush etc. It did not work.

2. Only when I shutdown the geronimo server, I am able to see the data
being flushed to the database.

3. I have even redeployed the app to see if the EntityManager is
flushing the data to the base. But no luck.

The question is, how can we flush the data to the database in a
controlled fashion from OpenJPA cache as sometimes we need the
committed values to be available in the database. ??

Thanks in advance.
Phani

Re: Entities not flushing into oracle database.

Posted by David Jencks <da...@yahoo.com>.
Hi Phani,

Which tranql wrapper are you using for the oracle db pool?  If you use  
the generic wrapper you have to set the commitOnAutocommit property to  
true as a workaround since oracle doesn't follow the jdbc spec which  
specified that it should commit pending work when you set autocommit  
true.  Getting this setting wrong could easily lead to the symptoms  
you observe.  On the other hand if you are using the oracle specific  
wrapper I think there might be some other problem.

thanks
david jencks

On Dec 29, 2008, at 11:26 PM, Phani Madgula wrote:

> Hi,
>
> I am using Apache Geronimo for my JPA applications. I am using oracle
> 10G database for my entities.
>
> I have an EAR application with an EJB and a WEB module. EJB module has
> an SLSB that uses Container Managed Transactions and uses Container
> Managed Persistence Manager (EntityManager injected by container). The
> code is as follows.
>
> ************
> package sample.jpa;
>
>
> import javax.ejb.EJBException;
> import javax.ejb.Remote;
> import javax.ejb.Stateless;
> import javax.ejb.TransactionAttribute;
> import javax.ejb.TransactionAttributeType;
> import javax.persistence.EntityManager;
> import javax.persistence.PersistenceContext;
> import javax.persistence.PersistenceContextType;
>
>
> @Stateless
> @Remote(AccountInterface.class)
> public class AccountBean implements AccountInterface {
>
>
>    @PersistenceContext(type=PersistenceContextType.TRANSACTION)
>    private EntityManager manager;
>
>
>    @TransactionAttribute(TransactionAttributeType.REQUIRED)
>    public Account open(int accountNumber) {
>        Account account = manager.find(Account.class, accountNumber);
>        if(account == null){
>        	account = new Account();
>        	account.ownerName = "anonymous";
>            account.accountNumber = accountNumber;
>            manager.persist(account);
>            manager.flush();
>            return account;
>        }else{
>        	throw new EJBException("Account already exists..!!. Account
> Number = "+accountNumber);
>        }
>
>    }
>
>    @TransactionAttribute(TransactionAttributeType.REQUIRED)
> 	public double getBalance(int accountNumber) {
>    	 Account account = manager.find(Account.class, accountNumber);
>        if(account==null)
>            throw new EJBException("Account not found..!!. Account
> Number = "+accountNumber);
>        return account.balance;
>    }
>
>    @TransactionAttribute(TransactionAttributeType.REQUIRED)
>    public void deposit(int accountNumber, double amount) {
>    	Account account = manager.find(Account.class, accountNumber);
>        if(account==null)
>        	throw new EJBException("Account not found..!!. Account Number
> = "+accountNumber);
>        double new_balance = account.getBalance() + amount;
>        account.setBalance(new_balance);
>        manager.flush();
>    }
>
>    @TransactionAttribute(TransactionAttributeType.REQUIRED)
>    public double withdraw(int accountNumber, double  amount) {
>    	
>    	Account account = manager.find(Account.class, accountNumber);
>    	
>        if(account==null)
>        	throw new EJBException("Account not found..!!. Account Number
> = "+accountNumber);
>
>        if (amount > account.getBalance()) {
>            return 0;
>        } else {
>        	double new_balance = account.getBalance() - amount;
>            account.setBalance(new_balance);
>            manager.flush();
>            return amount;
>        }
>    }
>
>
>
> }
> **************
>
> The Account.java is an entity.
>
> The WEB module has a servlet that looks up EJB to perform amount
> transfer from one account to another.
>
> The code is as follows.
>
> ******************
> package sample.jpa;
>
> import java.io.IOException;
> import java.io.PrintWriter;
>
> import javax.ejb.EJB;
> import javax.naming.Context;
> import javax.naming.InitialContext;
> import javax.persistence.EntityManager;
> import javax.persistence.PersistenceContext;
> import javax.servlet.ServletException;
> import javax.servlet.http.HttpServletRequest;
> import javax.servlet.http.HttpServletResponse;
> import javax.transaction.UserTransaction;
>
> /**
> * Servlet implementation class for Servlet: Test
> *
> */
> public class Test extends javax.servlet.http.HttpServlet implements
> javax.servlet.Servlet {
>   static final long serialVersionUID = 1L;
>
>
>   @PersistenceContext(unitName="AccountUnit")
>   private EntityManager em;
>
>   @EJB AccountInterface accountBean;
>
>    /* (non-Java-doc)
> 	 * @see javax.servlet.http.HttpServlet#HttpServlet()
> 	 */
> 	public Test() {
> 		super();
> 	}   	
> 	
> 	/* (non-Java-doc)
> 	 * @see javax.servlet.http.HttpServlet#doGet(HttpServletRequest
> request, HttpServletResponse response)
> 	 */
> 	protected void doGet(HttpServletRequest request, HttpServletResponse
> response) throws ServletException, IOException {
> 		// TODO Auto-generated method stub
> 		PrintWriter out = response.getWriter();
> 		
> 		int accNo1 = Integer.parseInt(request.getParameter("account1"));
> 		int  accNo2 = Integer.parseInt(request.getParameter("account2"));
> 		double amount = Double.parseDouble(request.getParameter("amount"));
> 		
> 		try{
> 			Context ctx = new InitialContext();
> 			UserTransaction ut =
> (UserTransaction)ctx.lookup("java:comp/UserTransaction");
> 			ut.begin();
> 			Account account = em.find(Account.class, accNo1);
> 			if(account.getBalance() < amount){
> 				throw new Exception("Account "+accNo1+" does not have enough
> balance "+amount);
> 			}else{
> 				out.println("Account ="+accNo1+" : Current balance  
> "+account.getBalance());
> 				accountBean.withdraw(accNo1, amount);
> 				out.println("Account ="+accNo1+" : Withdrawn "+amount);
> 				double balance = account.getBalance();
> 				out.println("Account ="+accNo1+" : After withdrawing the balance
> is "+balance);
> 				Account account2 = em.find(Account.class, accNo2);
> 				out.println("Account ="+accNo2+" : Current balance  
> "+account2.getBalance());
> 				accountBean.deposit(accNo2, amount);
> 				out.println("Account ="+accNo2+" : After depositing the balance is
> "+account2.getBalance());
> 			}
> 			em.flush();
> 			ut.commit();
> 		}catch(Exception e){
> 			throw new ServletException(e);
> 		}
> 	}  	
> 	
> 	/* (non-Java-doc)
> 	 * @see javax.servlet.http.HttpServlet#doPost(HttpServletRequest
> request, HttpServletResponse response)
> 	 */
> 	protected void doPost(HttpServletRequest request, HttpServletResponse
> response) throws ServletException, IOException {
> 		// TODO Auto-generated method stub
> 	}   	  	
> }
> ****************
>
> The persistence.xml file is as follows.
>
> ******************
>  <?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" version="1.0"
> xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
> http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
>
> <persistence-unit name="AccountUnit" transaction-type="JTA">
>  <description>ContainerManagedJPA</description>
>  <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</ 
> provider>
>  <jta-data-source>PhaniOraclePool</jta-data-source>
>  <class>sample.jpa.Account</class>
>  </persistence-unit>
> </persistence>
> ***************
>
> The "PhaniOraclePool" is the datasource deployed on the Geronimo
> server over Oracle database.
>
> Problems :
> **********
> 1. When the servlet is executed, the committed values are not flushing
> to Oracle database. After a transaction, when I query the database on
> SQLPLUS prompt, I still get the old values. I have used all possible
> methods like enititymanager.flush etc. It did not work.
>
> 2. Only when I shutdown the geronimo server, I am able to see the data
> being flushed to the database.
>
> 3. I have even redeployed the app to see if the EntityManager is
> flushing the data to the base. But no luck.
>
> The question is, how can we flush the data to the database in a
> controlled fashion from OpenJPA cache as sometimes we need the
> committed values to be available in the database. ??
>
> Thanks in advance.
> Phani