Spring MVC JdbcTemplate Transactional Annotation does not work - spring

I have two insert operation in one http post request. something like
#Service
public class StudentService {
#Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
public int create(final Student student) {
// insert into table 1
// insert into table 2 using id return from insert 1, but something BAD happen here
}
}
so, I added #Transactional at method level as shown above.
In order to make it work, I added this tx:annotation-driven
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
so my app-servlet.xml looks like
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
<mvc:annotation-driven />
<mvc:resources mapping="/res/**" location="/res/" />
<context:component-scan base-package="com.app" />
<bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
<bean id="dataSource" name="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://xxx:3306/AppDb" />
<property name="username" value="username" />
<property name="password" value="password" />
</bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
</beans>
the component-scan will basically scan all class include controller, service, model, viewmodel, helper class etc.
If I remove the tx:annotation-driven, the #transactional won't work.
But once I add this tx:annotation-driven, some error starts to appear, like
Error creating bean with name 'homeController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.app.service.StudentService com.app.controller.HomeController.studentRepository; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'studentService' defined in file [/path/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/MathSchool/WEB-INF/classes/com/app/service/StudentService.class]: Initialization of bean failed; nested exception is java.lang.NoClassDefFoundError: org/springframework/cglib/transform/impl/MemorySafeUndeclaredThrowableStrategy
How can I make this #transactional work.

Thanks to #Jens
My project using spring 4.1.6 and spring security 3.2.7
According to this documentation Migrating from Spring Security 3.x to 4.x (XML Configuration)
Spring Security 4 now requires Spring 4 (Spring 4.0 or 4.1, I guess). Conveniently, Spring Security
3.2.x works with Spring 3.2.x and Spring 4 (Spring 4.0 Only, I guess).
The only thing I did is downgrade Spring 4.1 to Spring 4.0

Related

Spring data jpa + Spring Transaction for multiple database

I am implementing multiple transaction(database) for my service using spring data jpa with #Transaction, having two persistent Unit names. And deploying in Jboss 6.4 EAP
spring xml includes
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-3.1.xsd">
<context:annotation-config />
<tx:annotation-driven />
<context:component-scan base-package="com.test.demo.domain.service" />
<context:component-scan base-package="com.test.demo.domain" />
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="demo-domain" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"></bean>
</property>
<property name="persistenceProviderClass" value="org.hibernate.ejb.HibernatePersistence" />
</bean>
<bean id="entityManagerFactoryMeta"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="demo-meta" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"></bean>
</property>
<property name="persistenceProviderClass" value="org.hibernate.ejb.HibernatePersistence" />
</bean>
<bean id="persistenceExceptionTranslationPostProcessor"
class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
<qualifier value="demoadmin"/>
</bean>
<bean id="transactionManagerMeta" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactoryMeta" />
<qualifier value="demoappmeta"/>
</bean>
<jpa:repositories base-package="com.test.demo.domain.repository" />
</beans>
Below are my service details
#Named(ServerConstants.SERVICE_DRAG_DROP)
**#Transactional("demoappmeta")**
public class DragDropService {
private static final Logger LOG = LoggerFactory.getLoggerFactory().getDomainLogger(ServerConstants.LOGGER_DOMAIN, DragDropService.class.toString());
#Inject
private TbAsmiDragDropRepository dragDropRepo;
public void createDragDrop(Message pMessage){
JSONObject requestJson = pMessage.getRequestObject().getRequestJson();
LOG.debug("inside createDragDrop() - Request : "+requestJson);
In Jboss I am unable to deploy it, I get the following exception:
Caused by: org.springframework.beans.factory.BeanCreationException:
Could not autowire field: private
com.test.demo.domain.repository.TbAsmiDragDropRepository
com.test.demo.domain.service.DragDropService.dragDropRepo; nested
exception is org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'tbAsmiDragDropRepository': Invocation
of init method failed; nested exception is
java.lang.IllegalArgumentException: Not an managed type: class
com.test.demo.domain.entity.TbAsmiDragDrop
If anything is missing or something is wrong, please advise
I found the solution just we have to set the attribute entity-manager-factory-ref="entitymanagerfactoryrefname" in
<jpa:repositories base-package="com.test.demo.domain.repository" entity-manager-factory-ref="entitymanagerfactoryrefname" />

Why does adding #Transactional causes exception org.springframework.beans.factory.BeanCreationException: Error creating bean with name?

I am learning Spring with Hibernate and I am playing a bit with my configuration to fully understand how it works. An answer to this will be quite helpful to understand what is going on. I have quite a perplexity about adding #Transactional to my #Repository object. When I add it I get the error:
WARNING: Exception encountered during context initialization - cancelling refresh attempt
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'soccerController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.edu.spring.soccer.service.AccountService com.edu.spring.soccer.controller.SoccerController.accountService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'accountService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.edu.spring.soccer.dao.AccountDaoImpl com.edu.spring.soccer.service.AccountService.accountDaoImpl; nested exception is java.lang.IllegalArgumentException: Can not set com.edu.spring.soccer.dao.AccountDaoImpl field com.edu.spring.soccer.service.AccountService.accountDaoImpl to com.sun.proxy.$Proxy63
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:298)
However when I delete the #Transactional everything works properly. I have read in several places that #Repository should be followed by #Transactional.
Following you see my configuration. This is the #Repository object with #Transactional. Note that extends an AbstractDao class that contains SessionFactory object.
#Repository
#Transactional //It causes the exception, without it, it works.
public class AccountDaoImpl extends AbstractDao implements AccountDao {
public void saveAccount(Account account, String password) {
//Both methods come from AbstractDao
persist(account);
insertPassword(account, password);
}
}
However when I delete the #Transactional everything works properly. I have read in several places that #Repository should be followed by #Transactional.
Following you see my configuration:
beans-data.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:jee="http://www.springframework.org/schema/jee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
<context:property-placeholder location="/WEB-INF/spring/environment.properties" />
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close" p:driverClassName="${dataSource.driverClassName}"
p:url="${dataSource.url}" p:username="${dataSource.username}"
p:password="${dataSource.password}" />
<!-- Taken from http://websystique.com/spring/spring4-hibernate4-mysql-maven-integration-example-using-annotations/ -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan">
<list>
<value>com.edu.spring.soccer.domain</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql:false}</prop>
<prop key="hibernate.format_sql">${hibernate.format_sql:false}</prop>
</props>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:annotation-driven />
<context:component-scan base-package="com.edu.spring.soccer.dao" />
</beans>
dispatcher-servlet.xml
I am doing the component-scan to all my packages and adding annotation-driven.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
<tx:annotation-driven />
<context:component-scan base-package="com.edu.spring.soccer.controller" />
<context:component-scan base-package="com.edu.spring.soccer.dao" />
<context:component-scan base-package="com.edu.spring.soccer.domain" />
<context:component-scan base-package="com.edu.spring.soccer.service" />
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/views/jsp/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
<mvc:resources mapping="/resources/**" location="/resources/" />
<mvc:annotation-driven />
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource"
p:basename="classpath:/messages" />
</beans>
Is it maybe related to having the component-scan and <tx:annotation-driven /> in the dispatcher-servlet.xml and then adding again #Transactional?.Maybe this causes some kind of redundancy.
The exception stack says it all :
nested exception is java.lang.IllegalArgumentException: Can not set com.edu.spring.soccer.dao.AccountDaoImpl field com.edu.spring.soccer.service.AccountService.accountDaoImpl to com.sun.proxy.$Proxy63
you are trying here to autowire AccountDaoImpl in your AccountService
But
AccountDaoImpl has that #Transactionnal annotation, so Spring has "proxied" it... You should autowire not the implementation but the interface, that is to say, in your AccountService change:
private AccountDaoImpl accountDaoImpl;
to
private AccountDao accountDao;
I believe it is not because of tx:annotation-driven & #Transactional. Whether in Hibernate or not, I m quite sure #Transactional have to be used at Service layer not #Repository Dao layer. What if you need to handle a transaction that spans across multiple Daos? Dao should be just cohesive components and transaction logic should reside in Service layer.
Pls see
http://www.byteslounge.com/tutorials/spring-with-hibernate-persistence-and-transactions-example
But I still see posts where #Transactional is used in Dao layer, and I disagree with it. But if u insist to use #Transactional and #Repository, maybe try put #Transactional on Dao method(s) saveAccount?

Spring #Autowired is not working for #WebService annotated class

Getting null pointer while trying to autowire.
Creating a Web application and using following webservices:
WebServiceEndpoint.java
#WebService
#Component
public class ChannelMapWebServiceEndpoint {
#Autowired
ChannelMapWebService webservice;
public ChannelMapInfo4[] getMaps() throws RemoteException {
return this.webservice.getMaps();
}
}
ChannelMapsebserviceImpl.java
#Service
public class ChannelMapWebServiceImpl implements ChannelMapWebService {
public ChannelMapInfo4[] getMaps() throws RemoteException {
System.out.println("hi");
}
}
application context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:annotation-config />
<context:component-scan base-package="ccad" />
<context:component-scan base-package="channelmapwebservice" />
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<value>/WEB-INF/jdbc.properties</value>
</property>
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
</beans>
I am getting the autowired object webservice as null while trying to connect through SoapUI.
The ChannelMapWebServiceEndpoint object serving your request class is not instantiated (and managed) by Spring, which is why Spring can't autowire any dependencies.
See the accepted answer for this question:
How to make an #WebService spring aware

mybatis configuration with spring3

I am trying to configure mybatis with spring 3. I am getting the following error while building my project.
Error creating bean with name 'datasource' defined in ServletContext resource [/WEB- INF/spring-servlet.xml]: Error setting property values; nested exception is org.springframework.beans.NotWritablePropertyException: Invalid property 'driver' of bean class [org.apache.commons.dbcp.BasicDataSource]: Bean property 'driver' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
My spring-servel.xml is
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">
<!-- Enable annotation driven controllers, validation etc... -->
<mvc:annotation-driven />
<context:component-scan
base-package="com.mycom.mycontroller.controller" />
<mvc:resources mapping="/resources/**" location="/resources/" />
<bean id="datasource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost/mydatabase"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.mycom.mydatabase.db.mybatis.sqlmap" />
</bean>
<bean id="viewResolver"
class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
Jar files. I have added are
commons-dbcp-1.4.jar
commons-pool-1.6.jar
mybatis-3.1.0.jar
mybatis-spring-1.1.1.jar
mysql-connector-java-5.1.18-bin.jar
org.springframework.transaction-3.1.1.RELEASE.jar
and other spring jars
Please let me know if you need anything for more clarification
Problem has nothing to do with myBatis.
org.apache.commons.dbcp.BasicDataSource has not any "driver" property. I think you should user driverClassName instead.
See doc.

Spring 3 newbie - NoSuchBeanDefinitionException - what have I missed?

Just started looking at spring 3 and MVC. I get the following exception...
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'registerController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private browniePoints.dao.UserDao browniePoints.web.RegisterController.userDao; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [browniePoints.dao.UserDao] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
From all the examples I have google this is all that is needed. What have I missed?
The interface...
package browniePoints.dao;
public interface UserDao
{
The implementation...
package browniePoints.dao.impl;
#Component
public class UserDaoImpl implements UserDao
{
#Autowired
private DataSource dataSource;
The controller...
package browniePoints.web;
#Controller
public class RegisterController
{
#Autowired
private UserDao userDao;
web.xml has one servlet that points to following xml config...
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<!-- Scans the classpath of this application for #Components to deploy as beans -->
<context:component-scan base-package="browniePoints.web" />
<!-- Configures the #Controller programming model -->
<mvc:annotation-driven />
<!-- Forwards requests to the "/" resource to the "index" view -->
<mvc:view-controller path="/" view-name="index"/>
<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources/ directory -->
<mvc:resources mapping="/resources/**" location="/resources/" />
<!-- point URLs ending .jsp to views in /WEB-INF/views -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"> </property>
<property name="prefix" value="/WEB-INF/views/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<!-- load properties from config.properites -->
<bean id="placeholderConfig" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="config.properties" />
</bean>
<!-- Define a SQL Server datasource -->
<bean id="dataSource" destroy-method="close" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
</beans>
Thanks.
Shot in the dark; you are missing the package of UserDaoImpl in your component-scan directive:
<context:component-scan base-package="x.z"/>

Resources