I can only get an active programmatic transaction in my spring (3.0.5) jdbc application, running on Oracle 11.2,
when the txAdvice points to the actual method (mainTest()) called from the application context (example "AAA" below).
If the txAdvice points to a child method (transactionTest()) of mainTest() (example "BBB" below) then I no longer have an active transaction.
Relevant code:
public class MainDS {
public static Controller cont;
public static void main(String[] args) {
String [] configList ={"spring.xml"};
ApplicationContext ctx = new ClassPathXmlApplicationContext(configList);
cont = (Controller)ctx.getBean("controller");
cont.mainTest();
}
}
public class Controller {
private JdbcTemplate jdbcTemplate;
public void mainTest()
{
transactionTest();
// MainDS.cont.transactionTest(); // also does not work
}
public void transactionTest(){
try {
// This prints "Transaction active = true" for AAA but "Transaction active = false" for BBB
System.out.println("Transaction active = " + TransactionSynchronizationManager.isActualTransactionActive() );
} catch (SQLException e) {
e.printStackTrace();
}
}
public JdbcTemplate getJdbcTemplate() {
return jdbcTemplate;
}
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
}
and my spring.xml file 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:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
<bean id="controller" class="Controller">
<property name="jdbcTemplate" ref="jdbcTemplate" />
</bean>
<bean id="txManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="main*" propagation="REQUIRED" /> <!-- AAA -->
<tx:method name="transaction*" propagation="REQUIRED" /> <!-- or BBB -->
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="myMethods" expression="execution(* *..Controller.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="myMethods" />
</aop:config>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="dataConfigPropertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="searchSystemEnvironment" value="true" />
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="initialSize" value="2" />
<property name="maxActive" value="2" />
<property name="url" value="my connection details" />
<property name="username" value="xxx" />
<property name="password" value="xxx" />
</bean>
</beans>
How do I get an active transaction for option BBB.
Any ideas very welcome.
Regards
DS
"BBB" case: the "mainTest()" method calls directly the "transactionTest()" method, omitting the aspect.
If you want to invoke the dynamically created proxy of the "transactionTest()" method, I suppose, you could do it through self bean reference (injected). Also as far as I remember, the spring manual used to suggest to call such methods via interface references (again using injected interface references).
Note: this is a really bad design! Implementation example (per request):
<bean id="controller" class="test.Controller">
<property name="jdbcTemplate" ref="jdbcTemplate"/>
<property name="instance" ref="controller" />
</bean>
public class Controller {
private JdbcTemplate jdbcTemplate;
private Controller instance;
public void mainTest() {
instance.transactionTest();
}
public void transactionTest() {
System.out.println("Transaction active = " + TransactionSynchronizationManager.isActualTransactionActive() );
}
public JdbcTemplate getJdbcTemplate() {
return jdbcTemplate;
}
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public Controller getInstance() {
return instance;
}
public void setInstance(Controller instance) {
this.instance = instance;
}
}
Transaction active = true
This behaviour is well documented in the spring manual (I recall it in the Aspects section), so you should definitely read it: http://docs.spring.io/spring-framework/docs/current/spring-framework-reference/html/aop.html section 9.6.1
More over, this question has already been covered here: One Service method invoke inner multiple method for Spring transaction
Related
I've been trying to deploy my project on my tomcat server but apparently, every time I try to start the server, I get this error in my catalina logs:
Exception encountered during context initialization - cancelling refresh attempt
org.springframework.beans.factory.BeanCreationException: Error creating bean with name
'mnpTranslationServiceImpl' defined in URL [file:/opt/tomcat/webapps/axis2/WEB-INF/springjdbc.xml]:
Error setting property values; nested exception is org.springframework.beans.NotWritablePropertyException: Invalid property 'mnpTranslationDAO' of bean class [com.e_horizon.jdbc.mnpTranslation.mnpTranslationServiceImpl]:
Bean property 'mnpTranslationDAO' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
here is my bean.xml which i named springjdbc.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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass" value="com.mysql.jdbc.Driver" />
<property name="jdbcUrl" value="jdbc:mysql://192.168.XX.X1:3306/msdp" />
<property name="user" value="root" />
<property name="password" value="ehorizon" />
<property name="minPoolSize" value="1" />
<property name="maxPoolSize" value="500" />
<property name="numHelperThreads" value="5" />
<property name="initialPoolSize" value="2" />
<property name="autoCommitOnClose" value="true" />
<property name="idleConnectionTestPeriod" value="60" />
<property name="maxIdleTime" value="1200" />
<property name="acquireRetryAttempts" value="2" />
</bean>
<bean id="dataSourceHD" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass" value="com.mysql.jdbc.Driver" />
<property name="jdbcUrl" value="jdbc:mysql://192.168.XX.X2:3306/hd" />
<property name="user" value="teligent" />
<property name="password" value="teligent" />
<property name="minPoolSize" value="1" />
<property name="maxPoolSize" value="500" />
<property name="numHelperThreads" value="5" />
<property name="initialPoolSize" value="2" />
<property name="autoCommitOnClose" value="true" />
<property name="idleConnectionTestPeriod" value="60" />
<property name="maxIdleTime" value="1200" />
<property name="acquireRetryAttempts" value="2" />
</bean>
<bean id="mpp2SubscribersDAO" class="com.e_horizon.jdbc.mpp2Subscriber.Mpp2SubscribersDAO">
<property name="dataSource">
<ref bean="dataSource" />
</property>
</bean>
<bean id="mpp2SubscribersService"
class="com.e_horizon.jdbc.mpp2Subscriber.Mpp2SubscribersServiceImpl">
<property name="mpp2SubscribersDAO">
<ref bean="mpp2SubscribersDAO" />
</property>
</bean>
<bean id="mnpTranslationDAO" class="com.e_horizon.jdbc.mnpTranslation.mnpTranslationDAO">
<property name="dataSource">
<ref bean="dataSourceHD" />
</property>
</bean>
<bean id="mnpTranslationServiceImpl" class="com.e_horizon.jdbc.mnpTranslation.mnpTranslationServiceImpl">
<property name="mnpTranslationDAO">
<ref bean="mnpTranslationDAO" />
</property>
</bean>
`
Here's the DAO file which the error says as not writable:
package com.e_horizon.jdbc.mnpTranslation;
import java.util.HashMap;
import java.util.Map;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.simple.SimpleJdbcInsert;
import com.e_horizon.www.jdbc.common.BaseDAO;
public class mnpTranslationDAO extends BaseDAO {
private SimpleJdbcInsert jdbcCall;
public static String TABLE = "MNP_TRANSLATION";
public static String FIELD_MSISDN = "msisdn";
public static String FIELD_ROUTING_NUMBER = "routing_number";
public static String FIELD_LAST_UPDATE = "last_update";
public static String FIELD_ACTION = "action";
protected RowMapper getObjectMapper () {
return new mnpTranslationMapper();
}
public void save (mnpTranslation mnp) {
this.jdbcCall = this.getSimpleJdbcInsert().withTableName(TABLE);
Map<String, Object> parameters = new HashMap<String, Object>();
parameters.put(FIELD_MSISDN, mnp.getMsisdn());
parameters.put(FIELD_ROUTING_NUMBER, mnp.getRouting_number());
parameters.put(FIELD_LAST_UPDATE, mnp.getLast_update());
parameters.put(FIELD_ACTION, mnp.getAction());
jdbcCall.execute(parameters);
}
}
Adding my model which contains the setters and getters (mnpTranslation.java):
package com.e_horizon.jdbc.mnpTranslation;
import java.sql.Timestamp;
public class mnpTranslation {
private String msisdn;
private String routing_number;
private Timestamp last_update;
private String action;
public void setMsisdn (String msisdn) {
this.msisdn = msisdn;
}
public String getMsisdn () {
return this.msisdn;
}
public void setRouting_number (String routing_number) {
this.routing_number = routing_number;
}
public String getRouting_number () {
return this.routing_number;
}
public void setLast_update (Timestamp last_update) {
this.last_update = last_update;
}
public Timestamp getLast_update () {
return this.last_update;
}
public void setAction (String action) {
this.action = action;
}
public String getAction () {
return this.action;
}
}
[edit] I'm adding the rest of my java files so you could see more what I'm dealing with right now. Thanks a lot for checking this.
mnpTranslationService.java:
package com.e_horizon.jdbc.mnpTranslation;
public abstract interface mnpTranslationService {
public abstract void save (mnpTranslation mnp);
}
mnpTranslationServiceImpl.java:
package com.e_horizon.jdbc.mnpTranslation;
public class mnpTranslationServiceImpl {
private mnpTranslationDAO mnpTranslationDAO;
public void save (mnpTranslation mnp) {
this.mnpTranslationDAO.save(mnp);
}
}
mnpTranslationMapper.java:
package com.e_horizon.jdbc.mnpTranslation;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.springframework.jdbc.core.RowMapper;
public class mnpTranslationMapper implements RowMapper {
public Object mapRow (ResultSet result, int dex) throws SQLException {
mnpTranslation mnp = new mnpTranslation();
mnp.setMsisdn(result.getString("msisdn"));
mnp.setRouting_number(result.getString("routing_number"));
mnp.setLast_update(result.getTimestamp("last_update"));
mnp.setAction(result.getString("action"));
return mnp;
}
}
Please let me know if there's anything else you need to see. I'd gladly post it right away. Any help will be much appreciated.
The error message states that the problem is with your mnpTranslationServiceImpl class.
See error message
Bean property 'mnpTranslationDAO' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
I have two transaction managers defined in my context file as follows
<tx:annotation-driven transaction-manager="firstTransactionManager" />
<bean id="secondDataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="---" />
<property name="url" value="datasource1" />
<property name="username" value="----" />
<property name="password" value="----" />
</bean>
<bean id="firstTransactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="firstDataSource" />
<qualifier value="firstTxManager"/>
</bean>
<bean id="secondTransactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="secondDataSource" />
<qualifier value="secondTxManager"/>
</bean>
<bean id="firstDataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="---" />
<property name="url" value="datasource2" />
<property name="username" value="---" />
<property name="password" value="---" />
</bean>
And I my class definitions are as follows
#Transactional("firstTransactionManager")
public class JdbcMain {
#Autowired
private static DataSource dataSource;
public DataSource getDataSource() {
return dataSource;
}
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
public static void main(String args[]){
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
TransactionExample example = (TransactionExample) ctx.getBean("transExample");
example.create();
}
}
And my example class is as follows:
#Transactional("secondTransactionManager")
public void create(DataSource dataSource2) {
try {
this.jdbcTemplate = new JdbcTemplate(dataSource2);
String sql = "insert into testtable values (?,?)";
getJdbcTemplate().update(sql,1,"1244343");
String marksSql="insert into testtable values (?,?)";
int i=2/0; //added to depict roll back behaviour of the transaction when exception occurs
getJdbcTemplate().update(marksSql,2,"sujay");
System.out.println("transaction committed");
} catch (RuntimeException e) {
throw e;
}
}
But the second transaction manager doesn't seem to work and the transaction is not rolled back (The first insert is executed). Can you provide me an idea.
I'm new to Spring and trying to get a example to work. But my application loads twice each time it starts. I think it could be a context problem because of my internet research and I have just one context.xml.
<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.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config/>
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:environment.properties</value>
</list>
</property>
<property name="ignoreUnresolvablePlaceholders" value="false"/>
</bean>
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:environment.properties</value>
</list>
</property>
<property name="ignoreUnresolvablePlaceholders" value="false"/>
</bean>
<bean name="objectMapper" class="com.fasterxml.jackson.databind.ObjectMapper" />
<bean name="restTemplate" class="org.springframework.web.client.RestTemplate">
<property name="requestFactory" ref="requestFactory" />
</bean>
<bean name="requestFactory" class="org.springframework.http.client.HttpComponentsClientHttpRequestFactory">
<property name="connectTimeout" value="10000" />
<property name="readTimeout" value="10000" />
</bean>
<bean name="httpClient" class="org.apache.http.client.HttpClient" factory-bean="requestFactory" factory-method="getHttpClient"/>
<bean name="TraderApplication" class="net.mrmoor.TraderApplication"/>
<bean name="API" class="com.iggroup.api.API"/>
<bean name="LightStreamerComponent" class="com.iggroup.api.streaming.LightStreamerComponent"/>
</beans>
My code of the TraderApplication Class is:
... skipped imports ....
#SpringBootApplication
public class TraderApplication implements CommandLineRunner{
private static final Logger log = LoggerFactory.getLogger(TraderApplication.class);
#Autowired
protected ObjectMapper objectMapper;
#Autowired
private API api;
#Autowired
private LightStreamerComponent lightStreamerComponent = new LightStreamerComponent();
private AuthenticationResponseAndConversationContext authenticationContext = null;
private ArrayList<HandyTableListenerAdapter> listeners = new ArrayList<HandyTableListenerAdapter>();
public static void main(String args[]) {
SpringApplication.run(TraderApplication.class, args);
}
#Override
public void run(String... args) throws Exception {
try {
if (args.length < 2) {
log.error("Usage:- Application identifier password apikey");
System.exit(-1);
}
String identifier = args[0];
String password = args[1];
String apiKey = args[2];
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("/public-api-client-spring-context.xml");
TraderApplication app = (TraderApplication) applicationContext.getBean("TraderApplication");
app.run(identifier, password, apiKey);
} catch (Exception e) {
log.error("Unexpected error:", e);
}
}
You mention in your comments above you got this working by removing SpringApplication.run(TraderApplication.class, args); but this would be removing spring-boot from your application so I'm going to assume since your question has a tag of [spring-boot] that this is not what you wanted. So here is an alternative way that you can configure beans using your xml.
#ImportResource({"classpath*:public-api-client-spring-context.xml"}) //Proper way to import xml in Spring Boot
#SpringBootApplication
public class TraderApplication implements CommandLineRunner {
...code you had before goes here
#Autowired
TraderApplication app;
#Override
public void run(String... args) throws Exception {
.. your parsing logic here
app.run(identifier, password, apiKey); //Now uses the autowired instance
}
}
You didn't list your pom.xml or build.gradle but it's important to remember that components you have registered in your context xml may be automatically configured in Spring Boot and you may not need to register them yourself in your xml.(Depending on which items you have starters for in your build file)
The setup I have an old project that is stuck to jdk 1.5, thus spring and hibernate versions are also the maximum possible to support this version of java. Hibernate is 3.3.2.GA and spring is 3.1.1.RELEASE. Setup is the following:
<persistence-unit name="myUnit" transaction-type="RESOURCE_LOCAL">
<mapping-file>persistence-query.xml</mapping-file>
...
<properties>
<property name="hibernate.max_fetch_depth" value="3" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="true" />
<property name="hibernate.hbm2ddl.auto" value="validate" />
<property name="hibernate.ejb.interceptor" value="com.myproj.common.dao.AuditInterceptor"/>
</properties>
</persistence-unit>
application context:
<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"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
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
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<context:component-scan base-package="..."/>
<tx:annotation-driven transaction-manager="transactionManager" />
<aop:aspectj-autoproxy/>
<bean id="applicationContextProvder" class="com.myproj.common.utils.ApplicationContextProvider"/>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate" >
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceXmlLocation" value="classpath:persistence.xml" />
<property name="persistenceUnitName" value="myUnit" />
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter" ref="jpaVendorAdapter" />
<property name="jpaDialect" ref="jpaDialect" />
</bean>
<bean id="jpaVendorAdapter"
class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="database" value="ORACLE" />
<property name="showSql" value="true" />
</bean>
<bean id="jpaDialect" class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
<!-- Local transaction management -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
<property name="dataSource" ref="dataSource" />
<property name="jpaDialect" ref="jpaDialect" />
</bean>
and my interceptor:
#Component
public class AuditInterceptor extends EmptyInterceptor {
private static final long serialVersionUID = 98658932451L;
#Autowired
private JdbcTemplate jdbcTemplate;
public void afterTransactionBegin(Transaction tx) {
if (user != null) {
jdbcTemplate.execute("call ah_audit_pkg.SetAudit('test')");
super.afterTransactionBegin(tx);
}
}
}
I run a junit to test that interceptor is getting called and it is not. In debug mode, I am able to see this:
Any help is appreciated! Why my intercetprot is not getting called.
Edit:
I also tried the interceptor to override the afterTransactionBegin but it didn't help.
I ended up with the following solution:
I have my entityt that extends from a superclass mapped entity:
#Entity
#Table(name = "my_table")
public class MyTable extends AuditInfo
The AuditInfo entity has the following mapping:
#MappedSuperclass
public abstract class AuditInfo implements Serializable {
...
#PrePersist
void onCreate() throws SQLException {
//this empty method is needed for AOP to trigger the audit information insert before entity is stored
}
#PreUpdate
void onPersist() throws SQLException {
//this empty method is needed for AOP to trigger the audit information insert before entity is updated
}
#PreRemove
void onRemove() throws SQLException {
//this empty method is needed for AOP to trigger the audit information insert before entity is removed
}
}
And the Aspect class:
#Aspect
#Component
public class MyAspect {
#Before("execution(* com.mypackage.entities.AuditInfo.on*(..))")
public void setAuditHistory(JoinPoint jp){
final AuditInfo info = ((AuditInfo)jp.getThis());
JdbcTemplate jdbcTemplate = ApplicationContextProvider.getApplicationContext().getBean(JdbcTemplate.class);
jdbcTemplate.execute(new CallableStatementCreator() {
public CallableStatement createCallableStatement(Connection conn) throws SQLException {
CallableStatement stmt = conn.prepareCall("begin ah_audit_pkg.SetAudit(?,?); end;");
stmt.setString(1, info.getAuditUser());
if(info.getAuditLocation() != null && info.getAuditLocation().trim().length() !=0) {
stmt.setString(2, info.getAuditLocation());
} else {
stmt.setString(2, info.getAuditUser());
}
return stmt;
}
}, new CallableStatementCallback<Object>() {
public Object doInCallableStatement(CallableStatement cs) throws SQLException, DataAccessException {
return cs.executeUpdate();
}
});
}
}
It is to be noted that the Spring beans are extracted from the context and not autowired - this is because AOP is a singleton class in spring implementation, and none of the autowired beans will be ever instantiated even if they are available in the context. So I had to manually retrieve them for later usage.
I am trying to save data to database with Spring's JdbcTemplate, but I get this error message. If I do it normal way with PreparedStatements it's working.
My CarDAO class:
#Repository
#Service
public class CarDAO implements CarDAOService {
private JdbcTemplate jdbcTemplate;
public JdbcTemplate getJdbcTemplate() {
return jdbcTemplate;
}
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public void saveCarToDB(CarBean carbean) {
final String sql = "insert into car (make, model) values (?,?)";
Object[] parameters = new Object[] {carbean.getMake()+
carbean.getModel()};
//if I do here system.out.print(Arrays.toString(parameters));
//it will print right make/model.
jdbcTemplate.update(sql, parameters);
//console says it is that row above, but I don't get how. Both parameters has values?
//WARNING: StandardWrapperValve[spring-dispatcher]: Servlet.service() for servlet
//springdispatcher threw exception
}
Spring-base.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<context:component-scan base-package="bean, dao" />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/Jsp/" />
<property name="suffix" value=".jsp" />
</bean>
<!-- DATA SOURCE -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="org.mariadb.jdbc.Driver" />
<property name="url" value="jdbc:mariadb://XXXXX" />
<property name="username" value="XXXXX" />
<property name="password" value="XXXXX" />
<property name="initialSize" value="1" />
<property name="maxActive" value="5" />
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
<mvc:annotation-driven />
</beans>
I didn't include my Controller or CarDAOService class, because I think the problem isn't there. They are forwarding right parameters to CarDAO class.
You need to put the #Autowired annotation on your setter:
#Autowired
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
Autowired bean via #Autowired, and it can be applied on setter method, constructor or a field.
Try this
#Autowired
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}