Spring Data JPA, MVC WebSphere 6.1.0.39 WebSphereUowTransactionManager - transaction
Hi All,
I have Spring MVC application build using Spring data JPA for database access and deployed in the Websphere 6.1.0.39. I want to use the TransactionManager to control the transactions and using the container specific one WebSphereUowTransactionManager. I had the same application working fine with Hibernate session factory and since when I migrated it use Spring Data Jpa we are getting bizarre error, complaining about transaction not being active. Followings are some config, code and error log.
Application context declaring entityManagerFactory
Code:
<bean id="jpaEntityManagerFactory" name="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="packagesToScan" value="com.mycompany.domain.model"/>
<property name="jpaDialect">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>
</property>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="${hibernate.show_sql}"/>
<property name="databasePlatform" value="${hibernate.dialect}"/>
</bean>
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.transaction.manager_lookup_class">org.hibernate.transaction.WebSphereExtendedJTATransactionLookup</prop>
<!-- prop key="hibernate.transaction.factory_class">org.hibernate.transaction.CMTTransactionFactory</prop -->
</props>
</property>
</bean>
<jpa:repositories base-package="com.mycompany.domain.repository"/>
<bean id="transactionManager" class="org.springframework.transaction.jta.WebSphereUowTransactionManager"/>
<tx:annotation-driven transaction-manager="transactionManager"/>
Filter entry in web.xml
Code:
<!--- JPA Open Session In View filter to allow objects to be lazy-loaded during page rendering -->
<filter>
<filter-name>jpaFilter</filter-name>
<filter-class>
org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter
</filter-class>
<init-param>
<param-name>entityManagerFactoryBeanName</param-name>
<param-value>entityManagerFactory</param-value>
</init-param>
<init-param>
<param-name>flushMode</param-name>
<param-value>MANUAL</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>jpaFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Following is the code for controller
Code:
Controller
@RequestMapping(value = "/admin/product-type")
public class ProductTypeAddAttributeController {
@Autowired
private AddRemoveAttributeService addRemoveAttributeService;
@Autowired
private AttributeLifeCycleManager attributeLifeCycleManager;
@RequestMapping(value = "{productTypeId}/add-attribute", method = RequestMethod.POST)
@ResponseBody
public String addAttributeToProductType(@PathVariable("productTypeId") ProductType productType,
@RequestParam("attributeId") String attributeId, @RequestParam("associationLevel") String associationLevelName)
throws ProductTypeNotUpdatedException {
LOGGER.debug("Attribute ID is {}", attributeId);
LOGGER.debug("Selected product type's id is {}", productType.getId());
LOGGER.debug("Association level is {}", associationLevelName);
Attribute attributeToBeAssociated = attributeLifeCycleManager.findById(Long.parseLong(attributeId));
AttributeAssociationLevelType associationLevel = obtainAssociationLevel(associationLevelName);
addRemoveAttributeService.addAttributeToProductType(attributeToBeAssociated, productType, associationLevel);
return SUCCESS_MESSAGE;
}
private AttributeAssociationLevelType obtainAssociationLevel(String associationLevelName) {
if (ASSOCIATED_WITH_PRODUCT.equals(associationLevelName)) {
return PRODUCT;
}
return SKU;
}
}
Code for AddRemoveAttributeService service used by Controller
Code:
@Service("attributeService")
@Transactional
public class DefaultAddRemoveAttributeService implements AddRemoveAttributeService {
@Autowired
private AttributeRepository attributeRepository;
@Autowired
private ProductTypeRepository productTypeRepository;
public void addAttributeToProductType(Attribute attributeToBeAssociated, ProductType productType,
AttributeAssociationLevelType associationLevel) {
if (productType.getProductAttributes().contains(attributeToBeAssociated)
|| productType.getSkuAttributes().contains(attributeToBeAssociated)) {
/*
* Attribute already associated. Do not add again
*/
LOGGER.error("Attribute already associated to product type");
throw new ProductTypeNotUpdatedException("Attribute already associated to product type");
} else {
if (associationLevel == AttributeAssociationLevelType.PRODUCT) {
productType.addProductAttribute(attributeToBeAssociated);
} else if (associationLevel == AttributeAssociationLevelType.SKU) {
productType.addSkuAttribute(attributeToBeAssociated);
}
if (productTypeRepository.save(productType) == null) {
LOGGER.error("Error updating product type.");
throw new ProductTypeNotUpdatedException("Error updating product type.");
}
}
}
}
Repository code
Code:
public interface ProductTypeRepository extends JpaRepository<ProductType, Long> {
@Query("FROM ProductType productType where productType.parent = null")
List<ProductType> findRootProductType();
List<ProductType> findBySearchNameIgnoreCase(String searchName);
}
And here is the logs
Code:
[12/12/12 11:22:16:867 GMT] 00000074 XATransaction E J2CA0030E: Method enlist caught java.lang.IllegalStateException: Transaction is inactive or prepared
at com.ibm.ws.Transaction.JTA.TransactionImpl.enlistResource(TransactionImpl.java:3289)
at com.ibm.ws.Transaction.JTA.TranManagerSet.enlist(TranManagerSet.java:407)
at com.ibm.ejs.j2c.XATransactionWrapper.enlist(XATransactionWrapper.java:699)
at com.ibm.ejs.j2c.ConnectionEventListener.localTransactionStarted(ConnectionEventListener.java:757)
at com.ibm.ws.rsadapter.spi.WSRdbManagedConnectionImpl.processLocalTransactionStartedEvent(WSRdbManagedConnectionImpl.java:1833)
I'll post more logs in next one,as we have restriction to not post more than 10000 charaters.
Could any one please take a look and provide some assistance? Thanks in advance
Thanks & Regards,
Irfan