Sunday, February 13, 2011

JPA NoResultException marks transaction rollback in WebLogic 10.3.2


The weblogic 10.3.2 server comes with two jpa implementations: eclipselink (org.eclipse.persistence_1.0.0.0_1-2-0.jar) and openjpa (org.apache.openjpa_1.0.1.0_1-1-1-SNAPSHOT.jar).  By default, it uses the openjpa. But you can add “<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>” to the persistence.xml to use the eclipselink implementation. 

Both implementations do not handle “NoResultException” properly. The “NoResultException”thrown in a transaction would mark the transaction as rolledback, which violates the JPA specification.

Some sample code (using EJB 3) is as follows:
@Stateless
public class FacadeImpl implements FacadeInf {
                        @EJB
                        DAOInf dAOInf;

                        public void findOrCreate(Long [] addressIds, PersonAddressData personAddressData) {
                        ..........
for (Long addressId: addressIds) {
try {
                                                                                                dAOInf.findByAddress(addressId);
}
catch(Exception e) { //find failed, try to create something
                                                                                                ....createInfo(personAddressData);
}
                                                }
                        }
}


@Stateless
public class DAOImpl implements DAOInf {

                        @PersistenceContext(unitName = "SampleJPA")
                        EntityManager em;

                        //@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
                        public Person findByAddress(Long addressId) {
                                                return (Person)em.createNamedQuery("someNamedQuery").getSingleResult();
                        }
}


In the above snippet,  if in the “for loop”, one invocation of “findByAddress” threw the “NoResultException”, the active transaction would be marked as rolledback, the “createInfo” in the “catch” block would not be able to accomplish anything. But if “@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)n the above snippet, if specification.edbackdd pselinkLogic 10.3.2
were not commented out, which means the “findByAddress” would run in a “NON transaction” context, in this case, even if the “find” function failed, the transaction could still continue, so the “createInfo” could be executed properly.

Most find functions (except findByPrimaryKey) in session bean DAOs should be marked as “Transaction NOT SUPPORTED” (@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)).

No comments:

Post a Comment