Data doesn't add to database in test - java

I have this test:
#ContextConfiguration(locations = {"classpath:/test/BeanConfig.xml"})
public class CandidateServiceTest extends AbstractTransactionalJUnit4SpringContextTests{
#Autowired
CandidateService candidateService;
#BeforeClass
public static void initialize() throws Exception{
UtilMethods.createTestDb();
}
#Before
public void setup() {
TestingAuthenticationToken testToken = new TestingAuthenticationToken("testUser", "");
SecurityContextHolder.getContext().setAuthentication(testToken);
}
#After
public void cleanUp() {
SecurityContextHolder.clearContext();
}
#Test
public void add(){
Candidate candidate = new Candidate();
candidate.setName("testUser");
candidate.setPhone("88888");
candidateService.add(candidate);//here I should add data to database
List<Candidate> candidates = candidateService.findByName(candidate.getName());
Assert.assertNotNull(candidates);
Assert.assertEquals("88888", candidates.get(0).getPhone());
}
}
add function:
#Transactional
#Service("candidateService")
public class CandidateService {
public void add(Candidate candidate) {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
String login = auth.getName();
User user = utilService.getOrSaveUser(login);
candidate.setAuthor(user);
candidateDao.add(candidate);
}
...
}
add function in dao:
public Integer add(Candidate candidate) throws HibernateException{
Session session = sessionFactory.getCurrentSession();
if (candidate == null) {
return null;
}
Integer id = (Integer) session.save(candidate);
return id;
}
Usually candidateService.add(candidate) adds to the database normally, but in test it doesn't add to database. I checked the database after test to see it.
What could be the problem?
UPDATE
configuration:
<?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:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee" xmlns:lang="http://www.springframework.org/schema/lang"
xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:util="http://www.springframework.org/schema/util"
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.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd
http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<!-- Настраивает управление транзакциями с помощью аннотации #Transactional -->
<tx:annotation-driven transaction-manager="transactionManager" />
<!-- Менеджер транзакций -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<!-- Непосредственно бин dataSource -->
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource"
p:driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver"
p:url="jdbc:sqlserver://10.16.9.52:1433;databaseName=hhsystemTest;"
p:username="userNew"
p:password="Pass12345" />
<!-- Настройки фабрики сессий Хибернейта -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation">
<value>classpath:test/hibernate.cfg.xml</value>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</prop>
<prop key="hibernate.connection.charSet">UTF-8</prop>
<!-- <prop key="hibernate.hbm2ddl.auto">create-drop</prop> -->
</props>
</property>
</bean>
</beans>

Try adding the #Transactional annotation around the method in your test class.
This annotation creates a session that can interact with the database.

Issue a flush after the candidateService.add. There is a transaction around the test method, a commit (and flush) is only happening after the method execution. You have to 'fake' the commit by flushing the session. Simply inject the SessionFactory in your test class and call flush on the current session.
#ContextConfiguration(locations = {"classpath:/test/BeanConfig.xml"})
public class CandidateServiceTest extends AbstractTransactionalJUnit4SpringContextTests{
#Autowired
private SessionFactory sessionFactory;
#Test
public void add(){
Candidate candidate = new Candidate();
candidate.setName("testUser");
candidate.setPhone("88888");
candidateService.add(candidate);//here I should add data to database
sessionFactory.getCurrentSession().flush(); //execute queries to database
List<Candidate> candidates = candidateService.findByName(candidate.getName());
Assert.assertNotNull(candidates);
Assert.assertEquals("88888", candidates.get(0).getPhone());
}
}
And ofcourse make sure that your findByName method is also implemented correctly and using the same hibernate session!

You must auto wire your sessionDactory instance in the DAO using #Autowired And I would place the #Transactional annotation within each method of the DAO, rather than before he class definition of a service class. This is normally the way that it is done in annotation-driven Spring application.

Related

Spring #Scheduled does not work appropriate

I have a method that should run at some delay, make request to api and add the new photo to database. So, addPhoto is working fine. It can print some info, make a request, but doesn't add the photo. I checked the database and there are only one photo, that i added manually.
#Component("restBean")
#Service
public class RestService {
private static final String url1 = "https://api.nasa.gov/mars-photos/api/v1/rovers/curiosity/photos?sol=1324&camera=fhaz&api_key=DEMO_KEY";
private PhotoDao photoDao;
#Autowired
public void setPhotoDao(PhotoDao photoDao) {
this.photoDao = photoDao;
}
#Scheduled(fixedRate = 5000)
public void addPhoto() {
System.out.println("TIME HAS COME");
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<Response> response = restTemplate
.getForEntity(url1,
Response.class);
Photo[] photos = response.getBody().getPhotos();
this.photoDao.save(photos[0]);
}
}
I have tested this method and all works except the last string. I checked that i get the response and can get the object from it.
this.photoDao.save(photos[0]);
That's my DAO class
#Repository
public class PhotoDaoImpl implements PhotoDao {
private static final Logger logger = LoggerFactory.getLogger(PhotoDaoImpl.class);
private SessionFactory sessionFactory;
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
#Override
public void save(Photo photo) {
Session session = this.sessionFactory.getCurrentSession();
session.persist(photo);
logger.info("Photo successfully saved. Photo details: {}", photo);
}
#Override
public Photo findOne(int id) {
Session session = this.sessionFactory.getCurrentSession();
Photo photo = (Photo) session.load(Photo.class, new Integer(id));
logger.info("Photo successfully loaded. Photo details: {}", photo);
return photo;
}
#Override
#SuppressWarnings("unchecked")
public List<Photo> getAll() {
Session session = this.sessionFactory.getCurrentSession();
That's my spring xml configuration
<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:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:task="http://www.springframework.org/schema/task"
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 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd">
<!-- This helps in mapping the logical view names to directly view files under a certain pre-configured directory -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!-- Database Information -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url"
value="jdbc:mysql://localhost:3306/DayDatabase"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>
<!-- Hibernate 4 SessionFactory Bean definition -->
<bean id="hibernate4AnnotatedSessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="packagesToScan">
<list>
<value>net.yan.model</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect
</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<!-- It register the beans in context and scan the annotations inside beans and activate them -->
<context:component-scan base-package="net.yan"/>
<!-- This allow for dispatching requests to Controllers -->
<mvc:annotation-driven/>
<mvc:default-servlet-handler/>
<!-- PhotoDao and PhotoService beans -->
<bean id="photoDao" class="net.yan.dao.PhotoDaoImpl">
<property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory"/>
</bean>
<bean id="photoService" class="net.yan.service.PhotoServiceImpl">
<property name="photoDao" ref="photoDao"/>
</bean>
<bean id="restService" class="net.yan.service.RestService">
<property name="photoDao" ref="photoDao"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory"/>
</bean>
<task:scheduled-tasks scheduler="myScheduler">
<task:scheduled ref="restBean" method="addPhoto" fixed-delay="5000"/>
</task:scheduled-tasks>
<task:scheduler id="myScheduler"/>
UPD: To be clear, i have another method, that make request and add to database. It's in the same class that doesn't work.
#EventListener(ContextRefreshedEvent.class)
#Transactional
public void contextRefreshedEvent() {
if (this.photoDao.checkDataBase()) {
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<Response> response = restTemplate
.getForEntity(url,
Response.class);
Photo[] photos = response.getBody().getPhotos();
this.photoDao.save(photos[0]);
}
}
UPD2: There's link to full project https://github.com/Kabowyad/Test-Project/tree/api-test/src/main/java/net/yan/service

Declartive Transaction in spring is not working

I am using spring declarative Transaction features. Something like this
XML file for spring configuration..
<?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: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.xsd">
<context:annotation-config/>
<context:component-scan base-package="com" />
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/test" />
<property name="username" value="root" />
<property name="password" value="password" />
</bean>
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver" >
<property name="prefix">
<value>/WEB-INF/pages/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
<!-- Add this tag to enable annotations transactions -->
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
</beans>
Dao Layer code
package com.dao;
#Repository("commonDao")
public class CommonDaoImpl implements CommonDao {
private static Logger logger = Logger.getLogger(CommonDaoImpl.class);
#Autowired
private DataSource dataSource;
private JdbcTemplate jdbcTemplate;
#Autowired
public void setSessionFactory(){
jdbcTemplate = new JdbcTemplate(dataSource);
}
#Override
public Object makePayment(Object e) {
String sql = "insert into payment (id, name, amount) values('abc', 100)";
try{
return jdbcTemplate.update(sql);
}catch(DataAccessException ex){
throw ex;
}
}
#Override
public Object signUp(Object e) {
String sql = "insert into login (userid, password) values('naveen', 'password')";
return jdbcTemplate.update(sql);
}
}
Service Layer code
#Service
public class CommonServiceImpl implements CommonService {
#Autowired
private CommonDao commonDao;
// #Transactional I tried both of them one by one but not worked
#Transactional(propagation=Propagation.REQUIRED, rollbackFor=Exception.class)
#Override
public boolean makePayment() {
try{
commonDao.signUp(new Object());
commonDao.makePayment(new Object());
} catch(DataAccessException ex){
return false;
}
return true;
}
}
but when i send call makePayment() method via controller then it save the record into login table but failed when it move to insert into payment table because i write query so that it can through an exception. I do not understand why transaction is not working. because #Transactional annotation is on makePayment method so not operation should happen in db.
Please tell what's wrong in this code.
Your SQL query in in makePayment method is :
insert into payment (id, name, amount) values('abc', 100)
You are asking the query to insert id, name and amount in the database table, but providing only 2 values i.e. abc and 100.
If id column in the table is autoincrement id then you don't need to mention it in the SQL query. Your SQL query in the makePayment method should be like this:
insert into payment (name, amount) values('abc', 100)

NPE SessionFactory in Spring/Hibernate integration

I'm a newbie in Spring and Hibernate and I'm having a NPE in this line:
Session session = getSessionFactory().getCurrentSession();
This is my UserDAO class
public class UserDAO implements IUserDAO{
private SessionFactory sessionFactory;
public SessionFactory getSessionFactory() {
return sessionFactory;
}
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
#Override
public Integer updateUser(User user) {
// TODO Auto-generated method stub
return null;
}
#Override
public User searchUserIfExists(String username, String password) {
Session session = getSessionFactory().getCurrentSession();
Query query = session.createQuery(SEARCH_USER_ACCT);
query.setParameter("username", username);
query.setParameter("password",password);
List<User> userList = query.list();
System.out.println(userList.size());
User user = null;
return user;
}
And this is my UserController
#SessionAttributes(value = {"userSession"})
#Controller
public class UserController {
private IUserDAO userDAO;
#Autowired
public UserController(IUserDAO userDAO) {
this.userDAO = userDAO;
}
#RequestMapping(value = "/processLogin.htm", method=RequestMethod.POST)
public String login(#ModelAttribute User user,#RequestParam("username") String username,
#RequestParam("password") String password,
HttpServletRequest request, HttpServletResponse response){
userDAO = new UserDAO();
User userOb = userDAO.searchUserIfExists(username, password);
if(userOb != null){
ModelAndView modelAndView = new ModelAndView();
String role = userOb.getUserRole();
switch(role){
case "admin":
modelAndView.addObject("userSession", userOb);
modelAndView.addObject("userId", userOb.getUserId());
modelAndView.setViewName("/adminPage_admin");
break;
case "customer":
modelAndView.addObject("userSession", userOb);
modelAndView.addObject("userId", userOb.getUserId());
modelAndView.setViewName("/customerpage_customer");
break;
}
}
return "";
}
}
This is my xml configuration for spring
<?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:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">
<!-- Enable #Controller annotation support -->
<mvc:annotation-driven />
<mvc:default-servlet-handler/>
<!-- Map simple view name such as "test" into /WEB-INF/test.jsp -->
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/jsp" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
<!-- Scan classpath for annotations (eg: #Service, #Repository etc) -->
<context:component-scan base-package="com.nacv2.*"/>
<context:spring-configured/>
<!-- JDBC Data Source. It is assumed you have MySQL running on localhost port 3306 with
username root and blank password. Change below if it's not the case -->
<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/db_nac"/>
<property name="username" value="root"/>
<property name="password" value=""/>
<property name="validationQuery" value="SELECT 1"/>
</bean>
<!-- Hibernate Session Factory -->
<bean id="mySessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="myDataSource"/>
<property name="packagesToScan">
<array>
<value>com.nacv2.model.*</value>
</array>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.connection.pool_size">${hibernate.connection.pool_size}</prop>
</props>
</property>
</bean>
<bean id="userDAO" class="com.nacv2.dataaccess.UserDAO">
<property name="sessionFactory" ref="mySessionFactory"/>
</bean>
<!-- Hibernate Transaction Manager -->
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="mySessionFactory"/>
</bean>
<!-- Activates annotation based transaction management -->
<tx:annotation-driven transaction-manager="transactionManager"/>
</beans>
Your problem is actually on this line:
userDAO = new UserDAO();
You have correctly wired Spring and Hibernate, but then you go and create a new object outside their knowledge, which won't know about the injected dependencies. Just use the one that's already been autowired for you.

How to close connection using session factory

I am new to spring mvc and hibernate.
How to close connection in spring mvc applction. I am very frustrated from this issue.
This is my code:
Dispatcher servlet:
<?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"
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:component-scan base-package="com.kqics" />
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/jsp/" p:suffix=".jsp" />
<bean id="userService" class="com.kqics.dao.kqtraveldao">
</bean>
<bean id="viewResolver1" class="org.springframework.web.servlet.view.ResourceBundleViewResolver">
<property name="order" value="1"/>
<property name="basename" value="views"/>
</bean>
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- one of the properties available; the maximum file size in bytes -->
<property name="maxUploadSize" value="10000000" />
</bean>
<import resource="db-config.xml" />
</beans>
dbconfig.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:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
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/beans http://www.springframework.org/schema/beans/spring-beans-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
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location"><value>/WEB-INF/jdbc.properties</value></property>
</bean>
<bean id="dataSourceBean" lazy-init="true" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="${jdbc.driverClassName}" />
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="user" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}"/>
<property name="acquireIncrement" value="${jdbc.acquireIncrement}" />
<property name="minPoolSize" value="${jdbc.minPoolSize}" />
<property name="maxPoolSize" value="${jdbc.maxPoolSize}" />
<property name="maxIdleTime" value="${jdbc.maxIdleTime}" />
<property name="numHelperThreads" value="${jdbc.numHelperThreads}" />
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"
p:dataSource-ref="dataSourceBean"
p:packagesToScan="com.kqics" >
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<!-- <prop key="hibernate.hbm2ddl.auto">create</prop> -->
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.connection.release_mode">after_transaction</prop>
<prop key="hibernate.connection.shutdown">true</prop>
</props>
</property>
</bean>
<!-- Transaction manager for a single Hibernate SessionFactory (alternative to JTA) -->
<tx:annotation-driven/>
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ><ref bean="sessionFactory"/></property>
</bean>
</beans>
my service class:
#Service
public class kqtravellogservice implements ikqtravellogservice {
#Autowired
ikqtraveldao iDao;
#Transactional
public void serviceaddnewvehicle(kqvehicle obj) {
// TODO Auto-generated method stub
iDao.addnewvehicle(obj);
}
#Transactional
public List<kqvehicle> servicefetchallvehicle() {
return iDao.fetchallvehicle();
}
#Transactional
public void serviceaddnewvehicletariff(kqvehicletariff obj,String tariff) {
iDao.addnewvehicletariff(obj,tariff);
}
dao impl
public class kqtraveldao implements ikqtraveldao {
private HibernateTemplate hibernateTemplate;
#Autowired
public void setSessionFactory(SessionFactory sessionFactory) {
try {
hibernateTemplate = new HibernateTemplate(sessionFactory);
} catch (Exception w) {
}
}
#Override
public void addnewvehicle(kqvehicle obj) {
hibernateTemplate.save(obj);
}
#SuppressWarnings("unchecked")
#Override
public List<kqvehicle> fetchallvehicle() {
List<kqvehicle> li=null;
li=hibernateTemplate.find("from kqvehicle");
return li;
}
#Override
public void addnewvehicletariff(kqvehicletariff obj, String tariff) {
try
{
hibernateTemplate.getSessionFactory()
.openSession()
.createSQLQuery("insert into "+tariff+" values(?,?,?,?,?)")
.setParameter(0, obj.getTid())
.setParameter(1, obj.getVehicletype())
.setParameter(2, obj.getRupees())
.setParameter(3, obj.getDateupto())
.setParameter(4, obj.getDatetimedetermined())
.executeUpdate();
}
catch(Exception e)
{
}
finally
{
hibernateTemplate.getSessionFactory().close();
}
}
Some friends told me as i am not using singleton, connection closing.. so, i got the too many connection error... Please advice me how to resolve this problem...
What are the changes is needed for my code....
The problem is in your dao, your save method is destroying springs proper tx management. You should NEVER call openSession() when you are using Spring to manage your connections and sessions.
Instead use a HibernateCallback which will give you a spring managed session.
#Override
public void addnewvehicletariff(final kqvehicletariff obj, final String tariff) {
hibernateTemplate.execute(new HibernateCallback() {
public Object doInHibernate(Session session) {
session.createSQLQuery("insert into "+tariff+" values(?,?,?,?,?)")
.setParameter(0, obj.getTid())
.setParameter(1, obj.getVehicletype())
.setParameter(2, obj.getRupees())
.setParameter(3, obj.getDateupto())
.setParameter(4, obj.getDatetimedetermined())
.executeUpdate();
}
}
}
Another note is that you shouldn't be using HibernateTemplate anymore, you should write code against the plain hibernate API using the getCurrentSession() method on the SessionFactory. See http://docs.spring.io/spring/docs/current/spring-framework-reference/html/orm.html#orm-hibernate-straight for more information.
public class kqtraveldao implements ikqtraveldao {
private SessionFactory sessionFactory;
#Autowired
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory=sessionFactory;
}
#Override
public void addnewvehicle(kqvehicle obj) {
sessionFactory.getCurrentSession().save(obj);
}
#SuppressWarnings("unchecked")
#Override
public List<kqvehicle> fetchallvehicle() {
return sessionFactory.getCurrentSession()
.createQuery("from kqvehicle")
.list();
}
#Override
public void addnewvehicletariff(kqvehicletariff obj, String tariff) {
sessionFactory.getCurrentSession()
.createSQLQuery("insert into "+tariff+" values(?,?,?,?,?)")
.setParameter(0, obj.getTid())
.setParameter(1, obj.getVehicletype())
.setParameter(2, obj.getRupees())
.setParameter(3, obj.getDateupto())
.setParameter(4, obj.getDatetimedetermined())
.executeUpdate();
}
}
just autowire the sessionfactory in the dao and remove the method set session factory.
#Autowired
private SessionFactory sessionfactory;
you can close the connection by calling sessionfactory.getCurrentSession().close() in your method.
the Session factory is the 'singleton' in your application.

Struts 2, Spring Plugin + Shiro integration: Autowiring issue

I have an issue with Struts2(2.3.15.1) Spring plugin. I use Shiro for security, and configure it with Annotations. The code looks like this:
public class Order2Action extends BaseAction {
#Autowired private UserDAO userDAO;
private static final Logger log = LoggerFactory.getLogger(Order2Action.class);
#Action(value = "list2",
results = {#Result(name = SUCCESS, location = "list.jsp")}
)
#RequiresRoles(ROLE_DATA_OPERATOR)
public String showOrderList() throws InterruptedException {
log.info("UserDAOImpl {}", userDAO);
return SUCCESS;
}
}
In this case UserDAO is not injected to Action. But if I comment out the string "#RequiresRoles(ROLE_DATA_OPERATOR)" - UserDAO is injected to Action.
What could be the problem here?
My ApplicationContext conf looks like this:
<?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"
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/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">
<!-- enable processing of annotations such as #Autowired and #Configuration -->
<context:annotation-config/>
<context:component-scan base-package="ee"/>
<bean id="makuDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
...
</bean>
<!--Shiro security configuration -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager"/>
<property name="loginUrl" value="/maku/auth/login"/>
<property name="unauthorizedUrl" value="/maku/auth/unauthenticated"/>
</bean>
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="cacheManager" ref="shiroCacheMan"/>
<property name="realm" ref="jdbcRealm"/>
</bean>
<bean id="jdbcRealm" class="org.apache.shiro.realm.jdbc.JdbcRealm">
<property name="dataSource" ref="makuDataSource"/>
<property name="credentialsMatcher">
<bean class="org.apache.shiro.authc.credential.PasswordMatcher"/>
</property>
</bean>
<bean name="shiroCacheMan" class="org.apache.shiro.cache.ehcache.EhCacheManager"/>
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
<!-- Enable Shiro Annotations for Spring-configured beans. Only run after -->
<!-- the lifecycleBeanProcessor has run: -->
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor">
<property name="proxyTargetClass" value="true" />
</bean>
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<property name="securityManager" ref="securityManager"/>
</bean>
</beans>
UserDAO:
public interface UserDAO {
User getByUsername(String username);
}
#Repository
public class UserDAOImpl extends AbstractJDBCDAO implements UserDAO {
#Override
public User getByUsername(String username){
return makuTmpl.queryForObject("select id, username, fullname from users where username=?",
new RowMapper<User>() {
#Override
public User mapRow(ResultSet rs, int i) throws SQLException {
User u = new User();
u.setId(rs.getLong( 1 ));
u.setUsername(rs.getString(2));
u.setFullname(rs.getString(3));
return u;
}
}, username);
}
}

Categories