Injecting a Spring Data repository with named queries into a service - java

I have the following repository, as simple as this:
package br.com.portal.repository;
public interface UserRepository extends CrudRepository<User, Long> {
#Query("SELECT u FROM User WHERE u.login = :login")
User findByLogin(#Param("login") String login);
}
Here, it's supposed to inherit all the common crud operations defined in CrudRepository and also expose the findByLogin function.
Most examples, if not all, do not annotate such repository with the #Repository annotation. Why is that? Is there a need to implement this interface or does the #Query somehow does it behind the scenes?
Here is what I currently have:
package br.com.portal.service;
public interface UserService {
User findByLogin(String login);
}
#Service
public class UserServiceImpl implements UserService {
private UserRepository repository;
#Autowired
public UserServiceImpl(UserRepository repository) {
this.repository = repository;
}
User findByLogin(String login) {
return repository.findByLogin(login);
}
}
And the spring-mvc.xml:
<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: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/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
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- Defines the static resources location, otherwise resource requests will result in 404 errors (not found) -->
<mvc:resources mapping="/assets/**" location="/assets/" order="0" cache-period="31556926" />
<mvc:resources mapping="/favicon.ico" location="/assets/icon/favicon.ico" cache-period="31556926" />
<!-- Defines the custom Spring components packages -->
<context:component-scan base-package="br.com.portal.repository">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Repository" />
</context:component-scan>
<context:component-scan base-package="br.com.portal.service">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Service" />
</context:component-scan>
<context:component-scan base-package="br.com.portal.controller">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>
<!-- JPA -->
<bean class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean" id="entityManagerFactory">
<property name="persistenceUnitName" value="default" />
</bean>
<bean class="org.springframework.orm.jpa.JpaTransactionManager" id="transactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
</beans>
I am not using Spring Boot.
With the current above informations, we should be able to reproduce the following error:
Error creating bean with name 'userServiceImpl' defined in file xxx: Unsatisfied dependency expressed through constructor parameter 0; nested exception is NoSuchBeanDefinitionException: No qualifying bean of type 'UserRepository'
Am I missing something?

Spring is telling you there's no bean named 'userServiceImpl', which looks correct. That text (case sensitive) doesn't exist. You should look at how to name the bean. You might just need to provide a name in the #Service annotation.

You need to tell spring to scan for repository interfaces to provide implementations for. With XML you do this by adding the namespace:
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
to the beans tag and then include this line
<jpa:repositories base-package="br.com.portal.repository"/>
inside. See this answer for more context.
You DO NOT NEED a #Repository annotation on your interface. That basically comes implicitly from extending CrudRepository

Annotate the UserRepository interface with #Repository

Related

Cannot autowire spring session bean by XML config

I have a simple app which is contains xml config, 1 spring session bean, controller. Everything works fine with an annotations, but looks like spring cannot see xml config because it cannot find Person bean?!
The question is how can i autowire beans through xml only?
Exception message:
No qualifying bean of type 'com.spring_beans_scope.beans.Person' available: expected at least 1 bean which qualifies as autowire candidate
<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: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/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="id1" class="com.spring_beans_scope.beans.WelcomeBean" scope="prototype">
<!--<property name="message" value="Welcome to spring" />-->
</bean>
<bean id="person" class="com.spring_beans_scope.beans.Person" scope="session">
<property name="name" value="Raj" />
<aop:scoped-proxy proxy-target-class="true" />
</bean>
<context:component-scan base-package="com.spring_beans_scope" />
<context:annotation-config />
</beans>
Bean
//#Service("person")
//#Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class Person {
private String name;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
The head of the controller
#Controller
public class HelloController {
#Autowired
private Person person;
This answer is based on your comment that you want to know how to do it without the use of annotations.
You can do it without annotations. You need to use the autowire attribute on your bean declaration.
autowire="byName"
This may be a bit trickier as the #Controller annotation is not configured from xml but this stack overflow post helps explain how you can configure your controller to do so.
This tutorial helps explain the different ways you can autowire from the context file directly.

why #autowired is not working when I access a bean

When I access a bean from spring bean configuration file using BeanFactory like this:
public class Person {
private String id,address;
#Autowired
private Customer customer;
//setters & getters
}
and bean configuration file
<bean name="person" class="com.ram.spring.model.Person"></bean>
<bean class="com.ram.spring.model.Customer">
<property name="email" value="ram#adp.com"></property>
<property name="name" value="Ram"></property>
</bean>
here is the executor class
public class PersonExecutor {
public static void main(String[] args) {
BeanFactory context = new XmlBeanFactory(new ClassPathResource("Spring.xml"));
Person person = (Person)context.getBean("person");
System.out.println(person.getCustomer());
}
}
when I execute this, I got null.is BeanFactory not supported for annotations?? any ideas??
Approach 1: Include below code in your xml
<beans xmlns="http://www.springframework.org/schema/beans"
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-3.0.xsd">
<context:annotation-config />
<!-- Remaining bean declaration -->
</beans>
Approach 2: Remove #Autowired and inject customer in your xml file only.
<bean name="person" class="com.ram.spring.model.Person">
<property name="customer" ref="customer"></property>
</bean>
<bean name="customer" class="com.ram.spring.model.Customer">
<property name="email" value="ram#adp.com"></property>
<property name="name" value="Ram"></property>
</bean>
You have to use AnnotationConfigApplicationContext or
you have to add to yor Spring.xml to activate the annotation scan.
As #jens suggested
you should active annotation scan
<context:component-scan base-package="package_path">
</context:component-scan>
<context:annotation-config />
hope that helped
Why doesn't it work?
When using Spring with an XML context, using annotations is not activated by default. This means #Autowired, #Transactional, #PostConstruct and any other annotation you will use will simply not be exploited.
How do I fix it?
To make Spring aware of annotations, you need to add the following line:
<context:annotation-config />
Thus, Spring will search for annotations in the beans it creates and process them accordingly.
This requires activating the context namespace. At the top of your context, make sure you have all context related links and arguments1:
<beans xmlns="http://www.springframework.org/schema/beans"
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-3.0.xsd">
<context:annotation-config />
<!-- Your context -->
</beans>
You do not need <context:component-scan /> in your case. This would be useful if you used full-annotation context (e.g. classes annotated with #Component). See the difference between <context:annotation-config /> and <context:component-scan /> in this answer.
Alternate solution
As Naman Gala suggested, you could also drop #Autowired completely and inject all dependencies in XML. See the related answer for more details.
1 This includes the xmlns:context attribute (xmlns = XML NameSpace) and two URLs in xsi:schemaLocation.

Autowired/Resource does not work when I remove spring-webmvc.jar

following the answer given in this question, I have removed the spring-webmvc.jar file from my lib to avoid a repetition with the one in the core project. However, when I do this, it seems that the #Autowired for at least a bean does not work any more.
The class having the #Autowired is the following (in which none of the field is filled):
public class SecurityUserCheckBeforeControllerHandler implements BeforeControllerHandler
{
#Resource(name = "userService")
private UserService userService;
#Autowired
private CMSPageContextService cmsPageContextService;
#Override
public boolean beforeController(final HttpServletRequest request, final HttpServletResponse response,
final HandlerMethod handler) throws IOException
{
// Code where the autowired fields are used (-> produces null pointer)
}
}
The spring configuration can be summarized as follows:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
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/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd">
<context:component-scan base-package="my.package" scope-resolver="de.hybris.platform.spring.IgnoreTenantScopeMetadataResolver" />
<mvc:annotation-driven ignore-default-model-on-redirect="true" validator="validator">
<mvc:message-converters>
<bean class="org.springframework.http.converter.ResourceHttpMessageConverter"/>
<bean class="org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter"/>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" />
</mvc:message-converters>
</mvc:annotation-driven>
<alias name="defaultBeforeControllerHandlersList" alias="beforeControllerHandlersList" />
<util:list id="defaultBeforeControllerHandlersList" >
<bean class="be.sbh.site.storefront.interceptors.beforecontroller.SecurityUserCheckBeforeControllerHandler" />
<!-- other beans in the list -->
</util:list>
<alias alias="cmsPageContextService" name="defaultCMSPageContextService" />
<bean id="defaultCMSPageContextService"
class="de.hybris.platform.acceleratorcms.services.impl.DefaultCMSPageContextService">
<!-- Properties -->
</bean>
<alias alias="userService" name="defaultUserService"/>
<bean id="defaultUserService" class="de.hybris.platform.servicelayer.user.impl.DefaultUserService" parent="abstractBusinessService">
<!-- Properties -->
</bean>
</beans>
If I follow the advise given in most of the similar questions (i.e. adding an #Component above the class that would be scanned), the bean will be created twice:
with the list given in the config file:
The autowired fields will be null which will still give a NullPointerException when the bean in the list is used
by the component-scan:
The fields are correctly autowired but the bean is not used in the list.
Strangely, if I put back the spring-webmvc.jar previously removed because of this question, the #Autowired will work as expected.
Trying to compare the stacktraces between the two configurations, I saw that the beans are created at different moments in the class org.springframework.context.support.AbstractApplicationContext during the startup of the server.
Last point: there is no error during the compilation and the startup of the server.
Do you have any idea for a solution please?
Thank you for reading me,
Laurent

#Autowired - No qualifying bean of type found for dependency

I've started my project by creating entities, services and JUnit tests for services using Spring and Hibernate. All of this works great.
Then I've added spring-mvc to make this web application using many different step-by-step tutorials, but when I'm trying to make Controller with #Autowired annotation, I'm getting errors from Glassfish during deployment. I guess that for some reason Spring doesn't see my services, but after many attempts I still can't handle it.
Tests for services with
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = {"classpath:/beans.xml"})
and
#Autowired
MailManager mailManager;
works properly.
Controllers without #Autowired too, I can open my project in web browser without trouble.
/src/main/resources/beans.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:context="http://www.springframework.org/schema/context"
xmlns:jdbc="http://www.springframework.org/schema/jdbc" 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-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
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-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/util http://www.springframework.org/schema/util/spring-util-3.0.xsd
http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_2_0.xsd">
<context:property-placeholder location="jdbc.properties" />
<context:component-scan base-package="pl.com.radzikowski.webmail">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>
<!--<context:component-scan base-package="pl.com.radzikowski.webmail.service" />-->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<!-- Persistance Unit Manager for persistance options managing -->
<bean id="persistenceUnitManager" class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
<property name="defaultDataSource" ref="dataSource"/>
</bean>
<!-- Entity Manager Factory for creating/updating DB schema based on persistence files and entity classes -->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitManager" ref="persistenceUnitManager"/>
<property name="persistenceUnitName" value="WebMailPU"/>
</bean>
<!-- Hibernate Session Factory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<!--<property name="schemaUpdate" value="true" />-->
<property name="packagesToScan" value="pl.com.radzikowski.webmail.domain" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
</props>
</property>
</bean>
<!-- Hibernate Transaction Manager -->
<bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<!-- Activates annotation based transaction management -->
<tx:annotation-driven transaction-manager="txManager"/>
</beans>
/webapp/WEB-INF/web.xml
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="WebApp_ID" version="2.4" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>Spring Web MVC Application</display-name>
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/mvc-dispatcher-servlet.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
/webapp/WEB-INF/mvc-dispatcher-servlet.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
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-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="pl.com.radzikowski.webmail" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>
<mvc:annotation-driven/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
</beans>
pl.com.radzikowski.webmail.service.AbstractManager
package pl.com.radzikowski.webmail.service;
import org.apache.log4j.Logger;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
/**
* Master Manager class providing basic fields for services.
* #author Maciej Radzikowski <maciej#radzikowski.com.pl>
*/
public class AbstractManager {
#Autowired
protected SessionFactory sessionFactory;
protected final Logger logger = Logger.getLogger(this.getClass());
}
pl.com.radzikowski.webmail.service.MailManager
package pl.com.radzikowski.webmail.service;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
#Component
#Transactional
public class MailManager extends AbstractManager {
// some methods...
}
pl.com.radzikowski.webmail.HomeController
package pl.com.radzikowski.webmail.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import pl.com.radzikowski.webmail.service.MailManager;
#Controller
#RequestMapping("/")
public class HomeController {
#Autowired
public MailManager mailManager;
#RequestMapping(value = "/", method = RequestMethod.GET)
public String homepage(ModelMap model) {
return "homepage";
}
}
Error:
SEVERE: Exception while loading the app
SEVERE: Undeployment failed for context /WebMail
SEVERE: Exception while loading the app : java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'homeController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: public pl.com.radzikowski.webmail.service.MailManager pl.com.radzikowski.webmail.controller.HomeController.mailManager; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [pl.com.radzikowski.webmail.service.MailManager] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
Sorry for a lot of code, but I don't know what can cause that error anymore.
Added
I've created the interface:
#Component
public interface IMailManager {
added implements:
#Component
#Transactional
public class MailManager extends AbstractManager implements IMailManager {
and changed autowired:
#Autowired
public IMailManager mailManager;
But it still throws errors (also when I've tried with #Qualifier)
..Could not autowire field: public
pl.com.radzikowski.webmail.service.IMailManager
pl.com.radzikowski.webmail.controller.HomeController.mailManager...
I've tried with different combinations of #Component and #Transactional too.
Shouldn't I include beans.xml in web.xml somehow?
You should autowire interface AbstractManager instead of class MailManager. If you have different implemetations of AbstractManager you can write #Component("mailService") and then #Autowired #Qualifier("mailService") combination to autowire specific class.
This is due to the fact that Spring creates and uses proxy objects based on the interfaces.
I had this happen because my tests were not in the same package as my components. (I had renamed my component package, but not my test package.) And I was using #ComponentScan in my test #Configuration class, so my tests weren't finding the components on which they relied.
So, double check that if you get this error.
The thing is that both the application context and the web application context are registered in the WebApplicationContext during server startup. When you run the test you must explicitly tell which contexts to load.
Try this:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = {"classpath:/beans.xml", "/mvc-dispatcher-servlet.xml"})
I was facing the same issue while auto-wiring the class from one of my jar file.
I fixed the issue by using #Lazy annotation:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
#Autowired
#Lazy
private IGalaxyCommand iGalaxyCommand;
This may help you:
I have the same exception in my project. After searching while I found that I am missing the #Service annotation to the class where I am implementing the interface which I want to #Autowired.
In your code you can add the #Service annotation to MailManager class.
#Transactional
#Service
public class MailManager extends AbstractManager implements IMailManager {
Spent much of my time with this! My bad! Later found that the class on which I declared the annotation Service or Component was of type abstract. Had enabled debug logs on Springframework but no hint was received. Please check if the class if of abstract type. If then, the basic rule applied, can't instantiate an abstract class.
Faced the same issue in my spring boot application even though I had my package specific scans enabled like
#SpringBootApplication(scanBasePackages={"com.*"})
But, the issue was resolved by providing #ComponentScan({"com.*"}) in my Application class.
Correct way shall be to autowire AbstractManager, as Max suggested, but this should work fine as well.
#Autowired
#Qualifier(value="mailService")
public MailManager mailManager;
and
#Component("mailService")
#Transactional
public class MailManager extends AbstractManager {
}
Can you try annotating only your concrete implementation with #Component? Maybe the following answer could help. It is kind of a similar problem. I usually put Spring annotations in the implementation classes.
https://stackoverflow.com/a/10322456/2619091
I ran in to this recently, and as it turned out, I've imported the wrong annotation in my service class. Netbeans has an option to hide import statements, that's why I did not see it for some time.
I've used #org.jvnet.hk2.annotations.Service instead of #org.springframework.stereotype.Service.
The solution that worked for me was to add all the relevant classes to the #ContextConfiguration annotation for the testing class.
The class to test, MyClass.java, had two autowired components: AutowireA and AutowireB. Here is my fix.
#ContextConfiguration(classes = {MyClass.class, AutowireA.class, AutowireB.class})
public class MyClassTest {
...
}
My guess is that here
<context:component-scan base-package="pl.com.radzikowski.webmail" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>
all annotations are first disabled by use-default-filters="false" and then only #Controller annotation enabled. Thus, your #Component annotation is not enabled.
One reason BeanB may not exist in the context
Another cause for the exception is the existence of two bean
Or definitions in the context bean that isn’t defined is requested by name from the Spring context
see more this url:
http://www.baeldung.com/spring-nosuchbeandefinitionexception
<context:component-scan base-package="com.*" />
same issue arrived , i solved it by keeping the annotations intact and in dispatcher servlet :: keeping the base package scan as com.*. this worked for me.
Instead of #Autowire MailManager mailManager, you can mock the bean as given below:
import org.springframework.boot.test.mock.mockito.MockBean;
::
::
#MockBean MailManager mailManager;
Also, you can configure #MockBean MailManager mailManager; separately in the #SpringBootConfiguration class and initialize like below:
#Autowire MailManager mailManager
This also happened to me when I had two methods with the same name marked #Bean in different #Configuration classes. It appears that one of the declarations was overriding the other.
If you are testing your controller.
Don't forget to use #WebAppConfiguration on your test class.
I had this happen because I added an autowired dependency to my service class but forgot to add it to the injected mocks in my service unit test.
The unit test exception appeared to report a problem in the service class when the problem was actually in the unit test. In retrospect, the error message told me exactly what the problem was.
I had faced the same problem,
Issue SOlved using below steps:
Check the class/Interface that you are auto wiring
For Interface Business logic we should use #service when it extends the Interface method.
For Dao that is a Database handling class we should use #Repository.
→ We can use #Service, #Repository and #Component annotation effectively and solve this issue very fast.
if you are testing the DAO layer you must use #Autowire annotation like this:
#Autowired
private FournisseurDao fournisseurDao;
Don't inject a repository element in the constructor
I've reproduced similar issue in multi-module project w/ No qualifying bean of type like:
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.example.stockclient.repository.StockPriceRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
and the reason for this error was missing annotation #EnableJpaRepositories in my specific use case.
To clarify: this annotation needs to be added for enabling auto configuration support for Spring Data JPA required to know the path of JPA repositories. By default, it will scan only the main application package and its sub packages for detecting the JPA repositories.
For more details you can refer, for instance, to this article.
Was configuring a non-SpringBoot, non-JPA, Hibernate application and the error was seen with injecting a DAO class implementation defined with #Repository.
Moving the declaration from #Repository to #Component worked. Remember that you would lose some features as mentioned here

Testing a service with mockito, ioC with autowiring

I'm trying to test a service with Mockito and testNG, but i have a couple of doubts. It's necessary create get/set to inject service, if service is declaredd like this:
#Autowired(required = true)
protected ITipService serveiTip;
when I'm trying to clean and package with maven I found this exception:
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'consultaDeutes' defined in URL
[file:/D:/workspaceGPT/GPT/gpt.ui/target/test-classes/applicationContext-gui-deutes-Test.xml]: Error setting property values; nested exception is org.springframework.beans.NotWritablePropertyException: Invalid property 'serveiTip' of bean class [cat.base.gpt.ui.ConsultaDeutesTest]: Bean property 'serveiTip' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
I believe that with autowiring get/set will be not necessary.
this is my test-context:
?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:mockito="http://www.mockito.org/spring/mockito"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.mockito.org/spring/mockito https://bitbucket.org/kubek2k/springockito/raw/tip/springockito/src/main/resources/spring/mockito.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<context:annotation-config/>
<context:component-scan base-package="cat.base.gpt.ui" />
<!-- mock del serveis que podem atacar per solicitar info -->
<mockito:mock id="serveiSubjecte" class="cat.base.tip.service.ISubjectesService"/>
<mockito:mock id="serveiTip" class="cat.base.tip.service.ITipService"/>
<mockito:mock id="serveiGpt" class="cat.base.gpt.domini.service.IGptService"/>
<mockito:mock id="sessio" class="cat.base.baseframe.session.IBaseSession"/>
<mockito:mock id="usuari" class="cat.base.baseframe.user.IBaseUser"/>
<!--
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="classpath:cat/base/bfp/ui/applicationResources" />
</bean>
-->
<bean name="consultaDeutes" class="cat.base.gpt.ui.ConsultaDeutesTest">
<property name="serveiTip" ref="serveiTip"/>
<property name="serveiGpt" ref="serveiGpt"/>
</bean>
</beans>
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:mockito="http://www.mockito.org/spring/mockito"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.mockito.org/spring/mockito https://bitbucket.org/kubek2k/springockito/raw/tip/springockito/src/main/resources/spring/mockito.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<context:annotation-config/>
<context:component-scan base-package="cat.base.gpt.ui" />
<!-- mock del serveis que podem atacar per solicitar info -->
<mockito:mock id="serveiSubjecte" class="cat.base.tip.service.ISubjectesService"/>
<mockito:mock id="serveiTip" class="cat.base.tip.service.ITipService"/>
<mockito:mock id="serveiGpt" class="cat.base.gpt.domini.service.IGptService"/>
<mockito:mock id="sessio" class="cat.base.baseframe.session.IBaseSession"/>
<mockito:mock id="usuari" class="cat.base.baseframe.user.IBaseUser"/>
<!--
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="classpath:cat/base/bfp/ui/applicationResources" />
</bean>
-->
<bean name="consultaDeutes" class="cat.base.gpt.ui.ConsultaDeutesTest"/>
<!-- WITH OUT PROPERTIES!!-->
</beans>
Using #Autowired will make spring automatically inject a matching bean into that field. Thus it is no longer required to define the "consultaDeutes" bean in the xml. If you'd like to use the xml definition, I believe you should define a setter for each property that you are trying to inject, eg: serveiTip, serveiGpt.
Using #Autowired in your test might require 2 additional annotation on the definition of your test class:
#ContextConfiguration(value = "/myContext.xml")
//#RunWith(SpringJUnit4ClassRunner.class) This is JUnit specific
#ActiveProfiles("dev")
public class TestCompareService {
#Autowired(required = true)
protected ITipService serveiTip;
....
}
I actually made a mistake pasting the #RunWith annotation specific for JUnit. For TestNG you can lookup this link. Apologies

Categories

Resources