I am attempting to create rest web services to handle CRUD operations for an android application. I'm using Spring 4.0 with Hibernate. I'm trying to autowire a dao and it's always null and I haven't been able to figure out the cause of the issue. I searched online and everything looks right to me so I'm at a complete lost. I defined the bean in the applicationContext as I have saw in many tutorials but I'm unable to get the dao to autowire. Any help would be appreciated.
dispatch-servlet.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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
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-4.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-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">
<context:annotation-config />
<mvc:annotation-driven />
<context:component-scan base-package="com.bike.party.services, com.bike.party.daos" />
<tx:annotation-driven transaction-manager="transactionManager" />
</beans>
applicationContext.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" id="propertyConfigurer" p:location="/WEB-INF/jdbc.properties"/>
<bean class="org.springframework.jdbc.datasource.DriverManagerDataSource" id="dataSource" p:driverClassName="${jdbc.driverClassName}" p:password="${jdbc.password}" p:url="${jdbc.url}" p:username="${jdbc.username}"/>
<!-- ADD PERSISTENCE SUPPORT HERE (jpa, hibernate, etc) -->
<bean class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" id="sessionFactory">
<property name="dataSource" ref="dataSource"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
<property name="packagesToScan" value="com.bike.party.models"/>
</bean>
<bean class="org.springframework.orm.hibernate4.HibernateTransactionManager" id="transactionManager" p:sessionFactory-ref="sessionFactory" />
<tx:annotation-driven/>
</beans>
UserDao
package com.bike.party.daos;
import com.bike.party.models.User;
public interface UserDao extends Dao<User> {
public User findByUserName(String username);
}
UserDaoImpl
package com.bike.party.daos;
import com.bike.party.models.User;
import java.util.List;
import javax.transaction.Transactional;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Repository;
#Repository
#Transactional
#Qualifier("userDaoImpl")
public class UserDaoImpl implements UserDao {
#Autowired
private SessionFactory sessionFactory;
#Override
public User findByUserName(String username) {
List<User> userList = sessionFactory.getCurrentSession().createCriteria(User.class).add(Restrictions.eq("username", username)).setMaxResults(1).list();
return userList.isEmpty() ? null : userList.get(0);
}
}
UserWebService
package com.bike.party.services;
import com.bike.party.daos.UserDao;
import com.bike.party.models.User;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.ext.Provider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
#Provider
#Component
#Path("userservice")
public class UserWebService {
#Autowired
private UserDao userDao;
#GET
#Path("/user/{username}")
#Produces(MediaType.TEXT_PLAIN)
public String getUser(String username) {
if (userDao == null) {
return "the dao is null";
}
User user = userDao.findByUserName(username);
if (user == null) {
return "No user was found.";
} else {
return user.getUsername();
}
}
}
UPDATE:
I modified the UserWebService with
private UserDao userDao;
#Autowired
public void setUserDao(UserDao userDao) {
if (functionDao != null) {
System.out.println(String.valueOf(userDao.findByUserName("chris")));
} else {
System.out.println("setting the dao is null :(");
}
this.userDao= userDao;
}
When the web app is deployed this is called and finds the user but when I call it from the client it is always null. Could this be because I'm calling the service directly and not going through spring? If so could any point me to the create way to call the service from the client. Thanks
i believe spring can not find your UserDao class.
try to change your component-scan instruction in dispatch-servlet.xml to this one:
<context:component-scan base-package="com.bike.party.*" />
If you're using Spring Tool Suite all #Component's in your project should be marked as Component(icon with S):
EDIT:
remove bean definition from xml, do not mix xml and annotated configuration.
Remove also "userDaoImpl" from your Annotations. Change #Repository("userDaoImpl") to #Repository()
Remove the <bean id="userDao" class="com.bike.party.daos.UserDaoImpl" /> bean from the applicationContext.xml file.
I think you are injecting this instance instead of the the one that gets created via the #Repository annotation which is why your SessionFactory is null
Try to derive your UserWebService from SpringBeanAutowiringSupport.
Related
I'm trying to use Spring #Cacheable on a Method but its Not Working.
import org.springframework.cache.annotation.Cacheable;
public class CacheableService {
#Cacheable(value = "entityCount")
public int someEntityCount(final String criteria) {
System.out.println("Inside function : " + criteria);
return 5;
} }
Beans Initialization :
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:cache="http://www.springframework.org/schema/cache"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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/cache http://www.springframework.org/schema/cache/spring-cache.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<cache:annotation-driven />
<context:annotation-config/>
<aop:aspectj-autoproxy />
<bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
<property name="caches">
<set>
<bean name = "impactLevelsCache" class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean">
<property name="name" value="impactLevels" />
</bean>
<bean name = "entityCountBean" class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean">
<property name="name" value="entityCount" />
</bean>
</set>
</bean>
</beans>
I am not Getting what mistake I'm making. It always invoking the method. I have also enabled Trace Logs but its not logging anything specific to Caching.
Also tried calling it from test cases, but cache not working. (Invocation is from different class. There is no Self-Invocation).
import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
#RunWith(SpringJUnit4ClassRunner.class)
// Using same Bean configuration for Testing also.
#ContextConfiguration(locations = "/com/amazon/pickuppointcapacity/test/appconfig2.xml")
public class RoughTest {
#Test
public void testSomeEntityCountCalledTwice_shouldCallDaoMethodOnce() {
CacheableService cacheableService = new CacheableService();
cacheableService.someEntityCount("A");
cacheableService.someEntityCount("A");
cacheableService.someEntityCount("A");
cacheableService.someEntityCount("A");
}
}
Please help me out.
You are creating a new instance of CacheableService in your test, which means it is not managed by Spring and non of the Spring annotations will work in it.
For spring to kick in, you need to get your service as a bean, autowired into your test class
I use xml configuration to declare my UserDao bean, and call it into another component: AuthenticationFacade (declared by #Component annotation) using #Autowired annotation like this:
applicationContext.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.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config />
<context:component-scan base-package="com.medkhelifi.tutorials.todolist"/>
<import resource="classpath:/conf/applicationContext-db.xml"/>
<import resource="classpath:/conf/applicationContext-security.xml"/>
</beans>
applicationContext-db.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"
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.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<!--.....-->
<!-- DAO BEANS -->
<bean id="userDao" class="com.medkhelifi.tutorials.todolist.models.dao.impl.UserDaoImp">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<!--....->
</beans>
AuthenticationFacade.java
package com.medkhelifi.tutorials.todolist.components;
import com.medkhelifi.tutorials.todolist.models.dao.UserDao;
import com.medkhelifi.tutorials.todolist.models.entities.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import javax.faces.bean.ManagedBean;
#Component
#ManagedBean
#Scope("session")
public class AuthenticationFacade implements IAuthenticationFacade {
#Autowired
private UserDao userDao;
public Authentication getAuthentication() {
return SecurityContextHolder.getContext().getAuthentication();
}
public User getAuthenticatedFacade() {
Authentication authentication = getAuthentication();
User user = userDao.findByUsername(authentication.getName());
return user;
}
}
With this configuration I get userDao as null, I don't know if I missed something.
There is where I use my AuthenticationFacade managedBean:
index.xhtml
<h:body>
<ui:composition template="templates/layout.xhtml">
<ui:define name="content">
<b:row>
<b:navBar brand="Brand" brandHref="#" fluid="true">
<!-- Following line is needed for TBS 3.0.1 (panel content overflow issue) -->
<b:navbarLinks pull="right"><b:navLink value=" " href="#"></b:navLink></b:navbarLinks>
<b:navbarLinks pull="right" styleClass="hidden-xs">
<b:dropMenu value="#{authenticationFacade.getAuthenticatedFacade().firstname}">
<b:navLink value="logout" href="#"></b:navLink>
</b:dropMenu>
</b:navbarLinks>
</b:navBar>
</b:row>
</ui:define>
</ui:composition>
</h:body>
After a few hours of searching, I found where I messed:
I forgot to add SpringBeanFacesELResolver to my faces-config.xml.
faces-config.xml
<application>
<!-- I forgot to add this resolver to my faces-config.xml -->
<el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
</application>
I am trying to learn spring MVC and created a rest service but I am getting bean autowiring problem.
Could not autowire field: taxApp.dao.daoImpl.userDaoImpl taxApp.controller.loginController.userService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [taxApp.dao.daoImpl.userDaoImpl] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency
The structure of my spring project looks like
src
main
java
taxApp
controller
loginController.java
model
user.java
dao
daoImpl
userDaoImpl.java
userDAO.java
resources
database
data-source-cfg.xml
user
spring-user.xml
spring-module.xml
webapp
web-inf
dispatcher-servlet.xml
web.xml
index.jsp
Following is how the files looks like
dispatcher-servlet.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<mvc:annotation-driven/>
<context:component-scan base-package="taxApp" />
<context:annotation-config />
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/pages/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
</beans>
spring-user.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<bean id="userDAO" class="dao.impl.userDaoImpl">
<property name="dataSource" ref="dataSource" />
</bean>
</beans>
spring-module.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- Using Oracle datasource -->
<import resource="database/data-source-cfg.xml" />
<import resource="dao/spring-user.xml" />
</beans>
All the other implementation like controller, DAO, service and model look like
loginController.java
#RestController
public class loginController {
#Autowired
userDaoImpl userService; //Service which will do all data retrieval/manipulation work
//other methods
}
userDAO.java
public interface userDAO {
public void insert(user _user);
public user findUserByEmail(String email);
}
userDaoImpl.java
public class userDaoImpl implements userDAO{
private DataSource dataSource;
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
//other methods
}
Mark your daoimpl as
#repository
public class userDaoImpl implements userDAO{}
Autowire interface rather marking an concrete class.
Go with java config for spring application much easier to understand.
Could you change the following:
#RestController
public class loginController {
#Autowired
userDaoImpl userService; //Service which will do all data retrieval/manipulation work
//other methods
}
by the following:
#RestController
public class loginController {
#Autowired
#Qualifier("userDAO")
userDaoImpl userService; //Service which will do all data retrieval/manipulation work
//other methods
}
and see the result?
u r having one setter injection in the bean u want to autowire u have to do something like this
//Autowired annotation on variable/setters is equivalent to autowire="byType"
#Autowired
private Employee employee;
#Autowired
public void setEmployee(Employee emp){
this.employee=emp;
}
I am following a tutorial of Spring. In the example it has created a method with #PostConstruct annotation. But I am trying to put but Spring throws Syntax Error.
Then Spring provide me 3 options:
Create a Annotation
Rename in file
Fix Project setup
Some one know what have I to do?
package cr.test.jba.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import cr.test.jba.entity.Role;
import cr.test.jba.repository.BlogRepository;
import cr.test.jba.repository.ItemRepository;
import cr.test.jba.repository.RoleRepository;
import cr.test.jba.repository.UserRepository;
#Service
public class InitDbService {
#Autowired
private RoleRepository roleRepository;
#Autowired
private UserRepository userRepository;
#Autowired
private BlogRepository blogRepository;
#Autowired
private ItemRepository itemRepository;
#PostConstruct
public void init(){
Role roleUser = new Role();
roleUser.setName("ROLE_USER");
}
And applicationContext:
<?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:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd">
<context:component-scan base-package="cr.test.jba">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<jdbc:embedded-database type="HSQL" id="datasource" />
<bean class ="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="emf">
<property name="packagesToScan" value="cr.test.jba.entity"></property>
<property name="dataSource" ref="datasource"></property>
<property name="jpaProperties">
<props>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">create</prop>
</props>
</property>
<property name="persistenceProvider">
<bean class="org.hibernate.jpa.HibernatePersistenceProvider" />
</property>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean class="org.springframework.orm.jpa.JpaTransactionManager" id="TransactionManager" >
<property name="dataSource" ref="datasource"></property>
</bean>
<jpa:repositories base-package="cr.test.jba.repository" entity-manager-factory-ref="emf" transaction-manager-ref="TransactionManager" />
</beans>
Looks like you have not imported the #PostConstruct annotation. Please add the below import statement:
import javax.annotation.PostConstruct;
When I am setting a value using #Value annotation from a property file, its not working, whereas setting using setter injection works.
my properties file like this.
app.work.dir=file:${user.home}/WORK
class file like below.
#Value("#{configProperties['app.work.dir']}")
private String workdir;
and this is my xml setting.
<util:properties id="configProperties" location="classpath:config.properties" />
when use setter injection like below then it works fine.
<bean id="sampleService" class="aaa.SampleService">
<property name="workdir" value="${app.work.dir}" />
</bean>
I'm not sure why and if possible i want to use #Value annotation.
please refer to junit test case below.
xml configulation:
<?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:context="http://www.springframework.org/schema/context" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:jpa="http://www.springframework.org/schema/data/jpa"
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/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<context:property-placeholder location="classpath:testconfig.properties" />
<util:properties id="sampleProperties" location="classpath:testconfig.properties" />
<bean id="exampleA" class="aa.sample.SampleA" />
<bean id="sampleB" class="aa.sample.SampleB" >
<property name="workdir" value="${work.dir}" />
<property name="tempdir" value="${work.dir.test}" />
<property name="aaa" value="${aaa}" />
</bean>
</beans>
sample service class:
package aa.sample;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
#Service
public class SampleA {
#Value("#{sampleProperties['work.dir']}")
private String workdir;
#Value("#{sampleProperties['work.dir.test']}")
private String tempdir;
#Value("#{sampleProperties['aaa']}")
private String aaa;
//getter setter deleted
}
properties file:
work.dir=file:${user.home}/WORK
work.dir.test=${work.dir}/TEST
aaa=bbb
and junit test class:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration({ "/testcontext.xml" })
public class ExampleTest {
#Inject
private SampleA sampleA;
#Inject
private SampleB sampleB;
#Test
public void testValueAnnotation() {
assertThat(sampleA.getAaa(), is("bbb"));//ok
String tempdir = sampleA.getTempdir();
String workdir = sampleA.getWorkdir();
assertFalse("[sampleA] temp dir should not have ${work.dir}", tempdir.indexOf("${work.dir}") >= 0);//ng
assertFalse("[sampleA] workdir dir should not have ${user.home}", workdir.indexOf("${user.home}") >= 0);//ng
}
}
The bean generated by
<util:properties id="sampleProperties" location="classpath:spring.properties" />
basically translates to a map. This notation
#Value("#{sampleProperties['work.dir']}")
requests one of its valued mapped with the key work.dir. There's no property resolution that occurs on the value returned. It's taken literally.
This, on the other hand,
<property name="tempdir" value="${work.dir.test}" />
requests a property, called work.dir.test which can be recursively resolved.