Autowire Jdbc template - spring

I am trying to auto-wire JDBC template and I'm getting a null pointer exception (template is null). What could be the problem?
#Autowired
template JdbcTemplate;
This is my application context xml:
<bean ..>
<mvc:annotation-driven />
<context:component-scan base-package="igate.dto" />
<context:component-scan base-package="igate.dao" />
<context:component-scan base-package="igate.service" />
<context:component-scan base-package="igate.controller" />
<context:component-scan base-package="igate.logs" />
<context:component-scan base-package="igate.testcases" />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"/>
<property name="suffix" value=".jsp" />
</bean>
<bean id="ds" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:#172.21.17.5:1521:oraten" />
<property name="username" value="lab01trg21" />
<property name="password" value="lab01oracle" />
</bean>
<bean id="template" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="ds"/>
</bean>
</beans>

Instead of this code:
#Autowired
template JdbcTemplate;
You need:
#Autowired
JdbcTemplate template;

The bean you try to inject in is not in the spring context;
No setter for the JdbcTemplate
You try to use the template in the constructor before the template is injeted

One reason for this error is to mix autowiring with manual
creation of beans.
For instance, you have a service class that autowires a bean.
#Service
public class CarService {
#Autowired
public JdbcTemplate jdbcTemplate;
// service code
}
But later intead of
#Autowired
private CarService carService;
you do:
CarService carService = new CarService();

Related

How to setup JTA with multiple XA datasoures for Spring JPA?

Spring JPA 4.2.1
Trying to setup JTA with 2 XA datasoures looks like below but gets NoUniqueBeanDefinitionException
"No qualifying bean of type [javax.persistence.EntityManagerFactory] is defined: expected single matching bean but found 2: emf_1,emf_2"
<bean id="emf_1"
class="...LocalContainerEntityManagerFactoryBean">
<property name="jtaDataSource" ref="xa_1" />
</bean>
<bean id="emf_2"
class="...LocalContainerEntityManagerFactoryBean">
<property name="jtaDataSource" ref="xa_2" />
</bean>
#Repository
public class DAO {
#PersistenceContext#Qualifier("emf_1")
private EntityManager em_1;
#PersistenceContext#Qualifier("emf_2")
private EntityManager em_2;
/*...*/
}
How to make it work?
#Solution
It works below now,
<bean class="...LocalContainerEntityManagerFactoryBean">
<property name="jtaDataSource" ref="xa_1" />
<property name="persistenceUnitName" value="pu_1" />
</bean>
<bean class="...LocalContainerEntityManagerFactoryBean">
<property name="jtaDataSource" ref="xa_2" />
<property name="persistenceUnitName" value="pu_2" />
</bean>
#Repository
public class DAO {
#PersistenceContext(unitName = "pu_1")
private EntityManager em_1;
#PersistenceContext(unitName = "pu_2")
private EntityManager em_2;
/*...*/
}
<persistence-unit name="pu_1" transaction-type="JTA">
...
</persistence-unit>
<persistence-unit name="pu_2" transaction-type="JTA">
...
</persistence-unit>

spring Multi DataSource #Service annotation with existing error

I have a code that is an error in the Spring Framework
Error Cause I know
So I do not know how to solve it the question.
I am being used with mybatis library
I had multi DataSource of two Account DataBase
I created a root-context.xml
-----------------------root-context.xml -----------------------------------------------------------
Oracle Account 1 Test1
<bean id="dataSourceTest1" class="org.apache.commons.dbcp.BasicDataSource" destroy-m
ethod="close">
<property name="driverClassName" value="net.sf.log4jdbc.DriverSpy"/>
<property name="url" value="jdbc:log4jdbc:oracle:thin:#111.111.1111.1111:1111:Test1"/>
<property name="username" value="TEST1"/>
<property name="password" value="TEST1"/>
<property name="maxIdle" value="200"/>
<property name="maxActive" value="200"/>
<property name="minIdle" value="5"/>
</bean>
<bean id="sqlSessionFactoryTest1" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSourceTest1" />
<property name="mapperLocations" value="classpath*:test/service/server/test1/**/*.xml" />
</bean>
<bean id="sqlSessionTest1" class="org.mybatis.spring.SqlSessionTemplate" name="sqlSessionTest1">
<constructor-arg name="sqlSessionFactory" ref="sqlSessionFactoryTest1" />
</bean>
<mybatis-spring:scan base-package="test.service.server.test1" template-ref="sqlSessionTest1" />
Oracle Account test2
<bean id="dataSourceTest2" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="net.sf.log4jdbc.DriverSpy"/>
<property name="url" value="jdbc:log4jdbc:oracle:thin:#222.222.2222.222:2222:Test2"/>
<property name="username" value="Test2"/>
<property name="password" value="Test2"/>
<property name="maxIdle" value="200"/>
<property name="maxActive" value="200"/>
<property name="minIdle" value="5"/>
</bean>
<bean id="sqlSessionFactoryTest2" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSourceTest2" />
<property name="mapperLocations" value="classpath*:test/service/server/test2/**/*.xml" />
</bean>
<bean id="sqlSessionTest2" class="org.mybatis.spring.SqlSessionTemplate" name="sqlSessionTest2">
<constructor-arg name="sqlSessionFactory" ref="sqlSessionFactoryTest2" />
</bean>
<mybatis-spring:scan base-package="test.service.server.test2" template-ref="sqlSessionTest2"/>
-----------------------root-context.xml END ---------------------------------------------------------
i am not used context:component-scan
<!-- <context:component-scan base-package="test.service.server.test1.test1service"/>-->
<!-- <context:component-scan base-package="test.service.server.test2.test2service"/>-->
I use the SpringJUnit4 each unit test
Were sequentially to (DataSourceTest and SqlSessionFactory Test and SqlSession Test mapperScanTest).
did not have any problems until mapperScanTest.
However, an error occurs when star using the annotation # Service
------------------------------------------service interface code ------------------------------------
public interface Test2_SERVICE {
public List<Test2_VO> GET_ListVO();
}
-------------------------------------------implement service code----------------------------------
#Service("Test2_SERVICE") *//<--Error annotaion*
public class Test2_SERVICEIMPLE implements Test2_SERVICE{
#Resource
Test2_MAPPER mapper;
#Override
public List<Test2_VO> GET_ListVO() {
return mapper.GET_ListMapperVO();
}
}
---------test Code------------------------------
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = { "file:src/main/**/*-context.xml" })
public class TestService {
Logger logger = Logger.getLogger(Thread.currentThread().getClass());
#Autowired
#Qualifier("Test2_SERVICE")
Test2_SERVICE test2_SERVICE;
#Override
public void testString() {
logger.info("---------------------");
List<Test2_VO> listVO = test2_SERVICE.GET_ListVO();
logger.info(listVO );
logger.info("---------------------");
}
}
Error Messages-----------------------------------
Caused by:
org.springframework.context.annotation.ConflictingBeanDefinitionException:
Annotation-specified bean name 'Test2_SERVICE' for bean class
[test.service.server.test2.test2service.Test2_SERVICE] conflicts with
existing, non-compatible bean definition of same name and class
[test.service.server.test2.test2service.Test2_SERVICEIMPLE]
------------------------------------------------end---------------------------------------------
#Service("Test2_SERVICE") *//<--Error annotaion*
The problem did not exist until the object Test2_MAPPER
However, the error begins in Test2_SERVICE
# Service ("Test2_SERVICE") Where there is only used here (Test2_SERVICEIMPLE).
Because of this problem
I am suffering for three days..
Somebody tell me solve the problem for this error message.
Thank you for reading my article.
The problem is that you create a bean with the name "Test2_SERVICE" for Test2_SERVICEIMPLE with this annotation:
#Service("Test2_SERVICE")
//creates the bean with id="TEST2_Service" of the type Test2_SERVICEIMPLE
public class Test2_SERVICEIMPLE implements Test2_SERVICE
and then assign exactly this Test2_SERVICEIMPLE bean to the interface Test2Service
#Autowired
#Qualifier("Test2_SERVICE")
//here you assign the bean of the not matching type Test2_SERVICEIMPLE to
//a variable of type Test2_SERVICE
Test2_SERVICE test2_SERVICE;
That means that the interface wants to use the bean for the implementation...
So just remove/change the #Qualifier("Test2_SERVICE") or change the name of the #Service("Test2_SERVICE")
How to autowire annotation qualifiers and how to name autodetected components

Spring autowire by constructor not working without setter method

Here is my Spring xml config:
<beans profile="test">
<context:annotation-config />
<!-- hsqldbDataSource bean for testing purposes -->
<bean id="hsqldbDataSource" class="com.zaxxer.hikari.HikariDataSource" destroy-method="shutdown">
<constructor-arg>
<bean class="com.zaxxer.hikari.HikariConfig">
<constructor-arg>
<props>
<prop key="dataSource.url">${hsqldb.url}</prop>
<prop key="dataSource.user">${user}</prop>
<prop key="dataSource.password">${password}</prop>
</props>
</constructor-arg>
<property name="dataSourceClassName" value="org.hsqldb.jdbc.JDBCDataSource" />
<property name="connectionTestQuery" value="SELECT 1" />
<property name="maximumPoolSize" value="5" />
<property name="minimumPoolSize" value="1" />
</bean>
</constructor-arg>
</bean>
<!-- execute a script to create tables after creation of bean for in-memory HSQLDB -->
<jdbc:embedded-database id="hsqldbDataSource" type="HSQL">
<jdbc:script location="classpath:schema.sql" />
<jdbc:script location="classpath:test-data.sql"/>
</jdbc:embedded-database>
<bean id="daoManager" class="com.d.DAOManager" autowire="constructor">
<property name="dataSource" ref="hsqldbDataSource"/>
</bean>
</beans>
And my DAOManager class:
public class DAOManager {
private DataSource dataSource;
private Connection connection;
#Autowired
public DAOManager(DataSource dataSource) {
this.dataSource = dataSource;
}
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
And here I call get my daoManager bean.
public static DAOManager createHSQLDBDAOManager() {
LOG.info("Setting up datasource to in-memory HSQLDB");
ConfigurableEnvironment env = (ConfigurableEnvironment)applicationContext.getEnvironment();
env.setActiveProfiles("test");
applicationContext.load("classpath:/applicationContext.xml");
applicationContext.refresh();
DAOManager daoManager = applicationContext.getBean("daoManager", DAOManager.class);
return daoManager;
}
Why is it complaining if I remove the setter method? I don't need it. If I remove the #Autowired before the constructor (it also works) it's just useless and not using the by constructor autowire function.
Needed to remove the property value of the daoManager bean
<bean id="daoManager" class="com.d.DAOManager" autowire="constructor"/>

how to get transaction supporting proxy from spring application context?

i need to use bean from spring application context not in a spring managed bean, so i do next: annotate bean with #Service annotation, so instance of bean created during spring loading.
<bean id="customRevisionListener" class="ru.csbi.registry.services.impl.envers.CustomRevisionListener" />
This instance is ApplicationContextAware, so application context is injected in this bean instance and i save it to static variable:
#Service
public class CustomRevisionListener implements EntityTrackingRevisionListener, ApplicationContextAware {
private static ApplicationContext applicationContext;
private ModelInformationService modelInformationService;
#Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
CustomRevisionListener.applicationContext = applicationContext;
}
private ModelInformationService getModelInformationService() {
if (modelInformationService == null) {
modelInformationService = applicationContext.getBean(ModelInformationService.class);
}
// TransactionProxyFactoryBean
return modelInformationService;
}
After that another instance of CustomRevisionListener created in not spring context(hibernate envers context). Here i use static variable to receive spring applicationContext
after that i'm getting beans from application context:
private ModelInformationService getModelInformationService() {
if (modelInformationService == null) {
modelInformationService = applicationContext.getBean(ModelInformationService.class);
}
the problem is that this bean has all #Autowired properties injected correctly:
#Service
public class ModelInformationServiceImpl implements ModelInformationService {
#Autowired
private EntityChangeService entityChangeService; // injected correctly
#Autowired
private PropertyService propertyService; // injected correctly
#Autowired
private ru.csbi.registry.services.reflection.HibernateDomainService hibernateService; // injected correctly
, but they are simple instances of java classes not Proxies supporting #Transactional annotation, which they are for my regular spring code:
getModelInformationService().getClass().getName() is "ru.csbi.registry.services.impl.envers.ModelInformationServiceImpl"
and must be something like
$Proxy71
How to get transaction supporting proxies, which spring genereates for example when injecting beans in #Controller, in bean not managed by spring?
i'm using next spring config:
<bean id="dataSource" class="org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy">
<constructor-arg ref="lazyConnectionDataSourceProxy"/>
</bean>
<bean id="lazyConnectionDataSourceProxy" class="org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy">
<property name="targetDataSource">
<ref local="dataSourceTarget" />
</property>
</bean>
<bean id="dataSourceTarget" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${ds.driver}" />
<property name="url" value="${ds.url}" />
<property name="username" value="${ds.user}" />
<property name="password" value="${ds.password}" />
<property name="initialSize" value="${ds.initialSize}" />
<property name="maxActive" value="${ds.maxActive}" />
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
<property name="dataSource" ref="dataSource" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<!--property name="entityInterceptor">
<bean class="ru.csbi.registry.utils.audit.AuditLogInterceptor">
<property name="sessionFactory" ref="auditSessionFactory" />
</bean>
</property-->
<property name="dataSource" ref="dataSource" />
<property name="lobHandler" ref="oracleLobHandler" />
<property name="packagesToScan" value="ru.csbi.registry.domain" />
<property name="hibernateProperties">
<bean id="hibernatePropertiesFactoryBean" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="locations">
<list>
<value>file:${realtyregistry.settings.path}/hibernate-config.properties</value>
</list>
</property>
</bean>
</property>
<property name="eventListeners">
<map>
<entry key="post-insert" value-ref="auditEventListener" />
<entry key="post-update" value-ref="auditEventListener" />
<entry key="post-delete" value-ref="auditEventListener" />
<entry key="pre-collection-update" value-ref="auditEventListener" />
<entry key="pre-collection-remove" value-ref="auditEventListener" />
<entry key="post-collection-recreate" value-ref="auditEventListener" />
</map>
</property>
</bean>
<bean id="auditEventListener" class="org.hibernate.envers.event.AuditEventListener" />
<bean id="persistenceManagerHibernate" class="ru.csbi.registry.utils.PersistenceManagerHibernate">
<property name="sessionFactory" ref="sessionFactory" />
</bean>

entitymanager is null on DAO class

I am trying to implement Spring MVC 3 +EclipseLink JPA 2
When I call saveUser for example it returns that
NullPointerException, EntityManager is
null
:
public class UserDAO {
#PersistenceContext
private EntityManager em;
public void setEntityManager(EntityManager em) {
this.em = em;
}
#Transactional
public User saveUser(User user){
return em.merge(user);
}
My config is:
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
<property name="dataSource" ref="dataSource"></property>
</bean>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="persistenceUnitName" value="application" />
<property name="jpaVendorAdapter">
<bean
class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter">
<property name="showSql" value="true" />
<property name="databasePlatform" value="org.eclipse.persistence.platform.database.MySQLPlatform" />
<property name="generateDdl" value="false" />
</bean>
</property>
<property name="loadTimeWeaver">
<bean
class="org.springframework.instrument.classloading.SimpleLoadTimeWeaver" />
</property>
</bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="username" value=".." />
<property name="password" value=".." />
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url"
value="jdbc:mysql://..." />
</bean>
Also have
<context:component-scan base-package="com.elasticbeanstalk.mypackage" />
<context:annotation-config />
It does initialize JPA during Tomcat startup. Why am I see NPE? Could I miss something?
If you instantiate the UserDAO manually, nothing will be injected by Spring. If the DAO is in a package which is under your base-package of <context:component-scan ../> then you can simply autowire it into your Controller. If not, either modify the base-package or also you can define the DAO in the appcontext manually, then you can autowire as well.

Resources