Autowired annotation error in spring with java - java

I have created a package com.springcore.autowire.Annotations which contains 4 files Emp.java, Address.java, awannconfig.xml, Test.java .
Emp.java contains class Emp with code as -
package com.springcore.autowire.Annotations;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
public class Emp {
private Address address;
public Address getAddress() {
return this.address;
}
#Autowired
#Qualifier("address")
public void setAddress(Address address) {
this.address = address;
}
public Emp(Address address) {
this.address = address;
}
#Override
public String toString() {
return "{" + " address='" + getAddress() + "'" + "}";
}
}
Address.java contains class Address with code-
package com.springcore.autowire.Annotations;
public class Address {
private String street;
private String city;
public String getStreet() {
return this.street;
}
public void setStreet(String street) {
this.street = street;
}
public String getCity() {
return this.city;
}
public void setCity(String city) {
this.city = city;
}
public Address(String street, String city) {
this.street = street;
this.city = city;
}
#Override
public String toString() {
return "{" + " street='" + getStreet() + "'" + ", city='" + getCity() + "'" + "}";
}
}
awannconfig.xml file -
<?xml version="1.0" encoding="UTF-8"?>
<!-- We get this template from documentation -->
<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-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:annotation-config />
<bean class="com.springcore.autowire.Annotations.Emp" name="emp" />
<bean class="com.springcore.autowire.Annotations.Address" name="address">
<property name="street" value="PA-24" />
<property name="city" value="Muradnagar" />
</bean>
<!-- more bean definitions go here -->
</beans>
Test.java contains Test class with main method to check use of #Autowired annotations .
package com.springcore.autowire.Annotations;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.ApplicationContext;
public class Test {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("com/springcore/autowire/Annotations/awannconfig.xml");
Emp obj = (Emp) context.getBean("emp");
System.out.println(obj);
}
}
When I run Test.java file it is showing this exception -
Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'emp' defined in class path resource [com/springcore/autowire/Annotations/awannconfig.xml]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'address' defined in class path resource [com/springcore/autowire/Annotations/awannconfig.xml]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'java.lang.String' available: expected at least 1 bean which qualifies as autowire candidate. Dependency
annotations: {}
Please help with this code as I cannot see any error.

The issue is coming due to parameterised constructor in the Address class whose constructor expects two parameters to be used to create a bean or object when you autowire it as there is no default constructor available.
Solution of the issue.
Keep Emp class as it is :
public class Emp {
private Address address;
public Address getAddress() {
return this.address;
}
#Autowired
#Qualifier("address")
public void setAddress(Address address) {
this.address = address;
}
public Emp(Address address) {
this.address = address;
}
#Override
public String toString() {
return "{" + " address='" + getAddress() + "'" + "}";
}
}
Keep Address class it is :
public class Address {
private String street;
private String city;
public String getStreet() {
return this.street;
}
public void setStreet(String street) {
this.street = street;
}
public String getCity() {
return this.city;
}
public void setCity(String city) {
this.city = city;
}
public Address(String street, String city) {
this.street = street;
this.city = city;
}
#Override
public String toString() {
return "{" + " street='" + getStreet() + "'" + ", city='" + getCity() + "'" + "}";
}
}
Update awannconfig.xml to this :
<?xml version="1.0" encoding="UTF-8"?>
<!-- We get this template from documentation -->
<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-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:annotation-config />
<bean class="com.springcore.autowire.Annotations.Emp" name="emp" />
<bean class="com.springcore.autowire.Annotations.Address" name="address">
<constructor-arg value="PA-24" type="String"/>
<constructor-arg value="Muradnagar" type="String"/>
</bean>
<!-- more bean definitions go here -->
</beans>
Output on my console.
{ address='{ street='PA-24', city='Muradnagar'}'}
Remember : Don't mix both constructor or setter injection as this will lead to confusion and unwanted errors.

Change bean configuration with constructor arg dependency injection, you missed that in emp bean definition. Change bean definition like below.
<bean class="com.springcore.autowire.Annotations.Emp" id="emp">
<constructor-arg ref = "address"/>
</bean>
<bean class="com.springcore.autowire.Annotations.Address" id="address">
<property name="street" value="PA-24" />
<property name="city" value="Muradnagar" />
</bean>

Related

Not able to autowire a bean using constructor in Spring

Im new to spring. I'm trying to autowire a bean using constructor using spring. Here is the code
<bean id="location" class="com.ibm.spring.Location">
<constructor-arg name="pincode" value="110976"></constructor-arg>
</bean>
<bean id="address" class="com.ibm.spring.Address">
<property name="id" value="2"></property>
<property name="street" value="shahjahan"></property>
</bean>
location class
public class Location {
private Address address;
private String pincode;
public void setAddress(Address address) {
this.address = address;
}
#Autowired
public Location(Address address, String pincode) {
super();
this.address = address;
this.pincode = pincode;
}
public void getTotalAddress() {
System.out.println(this.pincode + "::"+this.address);
}
}
Address class
public class Address {
private int id;
private String street;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = "Kkp";
}
#Override
public String toString() {
return "Address [id=" + id + ", street=" + street + "]";
}
Tester
public class SpringTester {
public static void main(String[] args) {
String configLoc = "com/ibm/spring/config/applicationContext.xml";
ApplicationContext ctx = new ClassPathXmlApplicationContext(configLoc);
Location l = (Location) ctx.getBean("location");
l.getTotalAddress();
}
}
I'm setting one of the field value through constructor arg. and class should be injected. WHat could be the problem here?
The error log says
Error creating bean with name 'location' defined in class path resource [com/ibm/spring/config/applicationContext.xml]: Unsatisfied dependency expressed through constructor parameter 0: Ambiguous argument values for parameter of type [com.ibm.spring.Address] - did you specify the correct bean references as arguments?
It seems like Location has two arguments so:
<bean id="location" class="com.ibm.spring.Location">
<constructor-arg name="pincode" value="110976"></constructor-arg>
<constructor-arg ref="address"></constructor-arg>
</bean>

Could not resolve matching constructor.Ambiguity issue with Spring dependency injection

I am getting the error "Could not resolve matching constructor (hint: specify index/type/name arguments for simple parameters to avoid type ambiguities)" while executing my spring program. I am new to Spring core and trying to learn the framework. Below is the code:
Student.java
package com.inject.test;
public class Student {
private String name;
private String className;
private Address address;
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
}
Address.java
package com.inject.test;
public class Address {
private String city;
private String state;
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
}
Test.java
package com.inject.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
#SuppressWarnings("resource")
ApplicationContext context = new ClassPathXmlApplicationContext("file:com/applicationContext.xml");
Student student = (Student) context.getBean("student");
System.out.println("Name: " + student.getName());
System.out.println("Class: " + student.getClassName());
Address studentAddress = student.getAddress();
System.out.println("Student Address: ");
System.out.println("City: " + studentAddress.getCity());
System.out.println("State: " + studentAddress.getState());
}
}
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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="student" class="com.inject.test.Student">
<property name="name" value="Jai"/>
<property name="className" value="MCA"/>
<constructor-arg ref="address" type="java.lang.String"/>
</bean>
<bean id="address" class="com.inject.test.Address">
<property name="city" value="Hyderabad"/>
<property name="state" value="Telangana"/>
</bean>
</beans>
What change should be made to resolve the constructor issue, please suggest.
Your xml configuration specifies a constructor argument containing the address, but your Student class does not have a constructor that takes any arguments.
Either add the appropriate constructor, or change the constructor-arg to a property in the xml configuration.
1)you have not added constructor in your class,so replace your applicationContext.xml file
<bean id="student" class="com.inject.test.Student">
<property name="name" value="jai"></property>
<property name="className" value="MCA"></property>
//instead of writing <constructor-arg>property write as follow
<property name="address" ref="addressOne"></property>
</bean>
<bean id="addressOne" class="com.inject.test.Address">
<property name="city" value="Hyderabad"/>
<property name="state" value="Telangana"/>
</bean>
or 2) just add
public Student(Address address) {
this.address = address;
}
in student class
and replace this line
<constructor-arg ref="address" type="java.lang.String"/>
with this
<constructor-arg ref="address"/>

Extend a crud-repository interface to handle JPA and mongo entities using spring-data

I have an application that currently uses relational DBs but could later move on to NoSQL DBs. In this case, I am trying to build my POJOs in such a way that it could be used for both type of DBs (relational and NoSQL). I have the following entities as defined below.
Base class:
package net.breezeware.runway.idm.entity;
import java.io.Serializable;
public abstract class SpringDataUser implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
protected long id;
protected String firstName;
protected String lastName;
protected String middleInitial;
protected String email;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getMiddleInitial() {
return middleInitial;
}
public void setMiddleInitial(String middleInitial) {
this.middleInitial = middleInitial;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("User ==> ");
sb.append("id = " + id + "; ");
sb.append("suemail = " + email + "; ");
sb.append("lastname = " + lastName + "; ");
sb.append("firstname = " + firstName + "; ");
sb.append("middleInitial = " + middleInitial);
return sb.toString();
}
}
JPA class:
package net.breezeware.runway.idm.entity.jpa;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.xml.bind.annotation.XmlRootElement;
import net.breezeware.runway.idm.entity.SpringDataUser;
#XmlRootElement
#Entity
#Table(name = "spring_data_user")
public class SpringDataUserJpa extends SpringDataUser {
/**
*
*/
private static final long serialVersionUID = 1L;
#Override
#Id
public long getId() {
return id;
}
#Override
public void setId(long id) {
this.id = id;
}
#Column(name = "last_name")
#Override
public String getLastName() {
return lastName;
}
#Override
public void setLastName(String lastName) {
this.lastName = lastName;
}
#Column(name = "email")
#Override
public String getEmail() {
return email;
}
#Override
public void setEmail(String suemail) {
this.email = suemail;
}
#Column(name = "first_name")
#Override
public String getFirstName() {
return firstName;
}
#Override
public void setFirstName(String firstName) {
this.firstName = firstName;
}
#Column(name = "middle_initial")
#Override
public String getMiddleInitial() {
return middleInitial;
}
#Override
public void setMiddleInitial(String middleInitial) {
this.middleInitial = middleInitial;
}
}
Mongo Class:
package net.breezeware.runway.idm.entity.mongo;
import net.breezeware.runway.idm.entity.SpringDataUser;
import org.springframework.data.mongodb.core.mapping.Document;
#Document(collection = "spring_data_users")
public class SpringDataUserMongo extends SpringDataUser {
/**
*
*/
private static final long serialVersionUID = 1L;
#Override
public long getId() {
return id;
}
#Override
public void setId(long id) {
this.id = id;
}
#Override
public String getEmail() {
return email;
}
#Override
public void setEmail(String email) {
this.email = email;
}
#Override
public String getLastName() {
return lastName;
}
#Override
public void setLastName(String lastName) {
this.lastName = lastName;
}
#Override
public String getFirstName() {
return firstName;
}
#Override
public void setFirstName(String firstName) {
this.firstName = firstName;
}
#Override
public String getMiddleInitial() {
return middleInitial;
}
#Override
public void setMiddleInitial(String middleInitial) {
this.middleInitial = middleInitial;
}
}
I am planning to build a DAO to access records using these entities. I would like to define a generic DAO and then extend that for different storage types as shown below.
Generic DAO:
package net.breezeware.runway.idm.dao;
import java.util.List;
import org.springframework.data.repository.NoRepositoryBean;
import org.springframework.data.repository.PagingAndSortingRepository;
#NoRepositoryBean
public interface SpringDataUserRepository<SpringDataUser> extends PagingAndSortingRepository<SpringDataUser, Long> {
List<SpringDataUser> findByEmail(String email);
List<SpringDataUser> findByLastName(String lastName);
}
JPA DAO:
package net.breezeware.runway.idm.dao.jpa;
import net.breezeware.runway.idm.dao.SpringDataUserRepository;
import net.breezeware.runway.idm.entity.jpa.SpringDataUserJpa;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Repository;
#Repository
#Profile("jpa")
public interface SpringDataUserJpaRepository extends SpringDataUserRepository<SpringDataUserJpa> {
}
Mongo DAO:
package net.breezeware.runway.idm.dao.mongo;
import net.breezeware.runway.idm.dao.SpringDataUserRepository;
import net.breezeware.runway.idm.entity.mongo.SpringDataUserMongo;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Repository;
#Repository
#Profile("mongo")
public interface SpringDataUserMongoRepository extends SpringDataUserRepository<SpringDataUserMongo> {
}
As you have noticed, I am trying to get help from spring-data's automatic DAO implementation generation feature as defined below.
Application Context File:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:mongo="http://www.springframework.org/schema/data/mongo"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
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-2.5.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.xsd
http://www.springframework.org/schema/jdbc
http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
http://www.springframework.org/schema/data/mongo
http://www.springframework.org/schema/data/mongo/spring-mongo.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">
<!-- Load all the property files required in the App. Files with prefix
'override' are used to set properties based on the environment. -->
<context:property-placeholder
location="classpath:runway.properties" />
<bean id="tejasCarestationProps"
class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="locations">
<list>
<value>classpath:conf/runwayidm.properties</value>
</list>
</property>
</bean>
<context:annotation-config />
<context:component-scan base-package="net.breezeware" />
<tx:annotation-driven />
<!-- NOTE: JNDI is NOT used to set DB properties. 'jdbc/AlstomDataSource
can be set in the context.xml file Tomcat's 'conf' directory. It was done
as an exercise to see if it works! -->
<!-- <jee:jndi-lookup id="runwayDataSource" jndi-name="jdbc/AlstomDataSource"
expected-type="javax.sql.DataSource" /> -->
<bean id="runwayDataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${database.driverClassName}" />
<property name="url" value="${database.url}" />
<property name="username" value="${database.username}" />
<property name="password" value="${database.password}" />
</bean>
<bean class="org.springframework.orm.jpa.JpaTransactionManager"
id="transactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="runwayDataSource" />
<property name="packagesToScan">
<list>
<!-- FIXME: Having the top level & wild cards in the package
value does not work. -->
<!-- <value>net.breezeware.alstom.groupcontrol</value> -->
<value>net.breezeware</value>
</list>
</property>
<property name="jpaVendorAdapter">
<bean
class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true" />
<property name="databasePlatform" value="${hibernate.dialectClass}" />
</bean>
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<jpa:repositories base-package="net.breezeware" entity-manager-factory-ref="entityManagerFactory"/>
<!-- ######################### Mongo DB ######################### -->
<mongo:mongo host="${mongodb.host}" port="${mongodb.port}" />
<mongo:db-factory id="mongoDbFactory" host="${mongodb.host}"
port="${mongodb.port}" dbname="${mongodb.dbname}" username="${mongodb.username}"
password="${mongodb.password}" />
<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
<constructor-arg name="mongoDbFactory" ref="mongoDbFactory" />
</bean>
I have included the Service class that uses the DAO to access the stores:
package net.breezeware.runway.idm.service.impl;
import java.util.List;
import net.breezeware.runway.idm.dao.SpringDataUserRepository;
import net.breezeware.runway.idm.entity.SpringDataUser;
import net.breezeware.runway.idm.service.api.IdmService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
#Service
public class IdmServiceImpl implements IdmService {
#Autowired
SpringDataUserRepository<SpringDataUser> springDataUserRepository;
#Transactional
public SpringDataUser saveSpringDataUser(SpringDataUser user) {
// return springDataUserRepository.save(user);
return null;
}
#Transactional
public List<SpringDataUser> findSpringDataUsersByLastName(String lastName) {
return springDataUserRepository.findByLastName(lastName);
}
#Transactional
public List<SpringDataUser> findAllSpringDataUsers() {
return (List<SpringDataUser>) springDataUserRepository.findAll();
}
}
I have the following Application file that serves as the entry point to the App:
package net.breezeware.runway.idm;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
#Configuration
#ImportResource(value = {"classpath:applicationContext.xml"})
#EnableAutoConfiguration
#ComponentScan
public class IdmApplication {
public static void main(String[] args) throws Exception {
Logger logger = LoggerFactory.getLogger(IdmApplication.class);
SpringApplication.run(IdmApplication.class, args);
logger.info("Inside main method of IdmApplication");
}
}
Here is he code I have to test the service functionality.
package net.breezeware.runway.idm;
import net.breezeware.runway.idm.entity.SpringDataUser;
import net.breezeware.runway.idm.entity.jpa.SpringDataUserJpa;
import net.breezeware.runway.idm.service.api.IdmService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.testng.AbstractTestNGSpringContextTests;
import org.testng.annotations.Test;
//#ContextConfiguration({"classpath:**/applicationContext.xml"})
// #EnableAutoConfiguration
// #ComponentScan
#ActiveProfiles(profiles = {"jpa"})
// #WebAppConfiguration
#SpringApplicationConfiguration(classes = IdmApplication.class)
public class IdmServicesJpaTest extends AbstractTestNGSpringContextTests {
Logger logger = LoggerFactory.getLogger(IdmServicesJpaTest.class);
#Autowired
private IdmService idmService;
#Test
public void createSpringDataUserTest() {
logger.info("========== createSpringDataUserTest() ==========");
SpringDataUser user = new SpringDataUserJpa();
try {
user.setId(1);
user.setEmail("mark#gmail.com");
user.setFirstName("mark");
user.setLastName("adams");
user.setMiddleInitial("");
logger.info("SpringDataUser to be saved = " + user);
SpringDataUser savedUser = idmService.saveSpringDataUser(user);
logger.info("Saved User = " + savedUser);
} catch (Exception e) {
logger.info("Exception Occured = " + e);
}
}
}
I would like to use the 'Profile' feature in Spring to choose the DAO implementation in run-time. I expect the code to work, but unfortunately I have trouble getting the DAO interfaces to be autowired into Service classes. It seems like the DAO/Repository implementations for the SpringDataUserRepository is not not created by Spring-Data. Here is the error in my log file when I try to run the test.
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:291)
at org.testng.SuiteRunner.run(SuiteRunner.java:240)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1224)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1149)
at org.testng.TestNG.run(TestNG.java:1057)
at org.apache.maven.surefire.testng.TestNGExecutor.run(TestNGExecutor.java:70)
at org.apache.maven.surefire.testng.TestNGDirectoryTestSuite.execute(TestNGDirectoryTestSuite.java:109)
at org.apache.maven.surefire.testng.TestNGProvider.invoke(TestNGProvider.java:111)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:164)
at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:110)
at org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:175)
at org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcessWhenForked(SurefireStarter.java:107)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:68)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'idmServiceImpl': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: net.breezeware.runway.idm.dao.SpringDataUserRepository net.breezeware.runway.idm.service.impl.IdmServiceImpl.springDataUserRepository; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [net.breezeware.runway.idm.dao.SpringDataUserRepository] 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)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:292)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1185)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:700)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:760)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:691)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:320)
at org.springframework.boot.test.SpringApplicationContextLoader.loadContext(SpringApplicationContextLoader.java:107)
at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContextInternal(CacheAwareContextLoaderDelegate.java:64)
at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContext(CacheAwareContextLoaderDelegate.java:91)
... 38 more
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: net.breezeware.runway.idm.dao.SpringDataUserRepository net.breezeware.runway.idm.service.impl.IdmServiceImpl.springDataUserRepository; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [net.breezeware.runway.idm.dao.SpringDataUserRepository] 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)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:508)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:289)
... 53 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [net.breezeware.runway.idm.dao.SpringDataUserRepository] 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)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1100)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:960)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:855)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:480)
... 55 more
I just could not get the DAOs instantiated/autowired into the Service class. I have tried different settings like marking the base entity Object 'SpringDataUser' with #MarkedSuperclass and such, but nothing seems to work.
Please let me know if I am missing something. I have spent a considerable amount of time on StackOverflow to find an answer but could not find one that solves my problem.
Thanks in advances.

Error setting property values; nested exception is org.springframework.beans.NotWritablePropertyException:

I was trying to get data from a MySQL database using the Spring utility ResultSetExtractor, but I got the following exception:
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'edao' defined in class path resource [applicationContext2.xml]: Error setting property values; nested exception is org.springframework.beans.NotWritablePropertyException: Invalid property 'jdbcTemplate' of bean class [org.resultset.EmployeeDao]: Bean property 'jdbcTemplate' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1344)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1067)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:511)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:450)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:290)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:287)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:189)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:562)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:871)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:423)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
at org.resultset.Test.main(Test.java:11)
Caused by: org.springframework.beans.NotWritablePropertyException: Invalid property 'jdbcTemplate' of bean class [org.resultset.EmployeeDao]: Bean property 'jdbcTemplate' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:1012)
at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:857)
at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:76)
at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:58)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1341)
... 13 more
Employee.java
public class Employee {
private int id;
private String name;
private float salary;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public float getSalary() {
return salary;
}
public void setSalary(float salary) {
this.salary = salary;
}
public Employee(int id, String name, float salary) {
super();
this.id = id;
this.name = name;
this.salary = salary;
}
public Employee()
{
}
}
EmployeeDao.java
public class EmployeeDao {
private JdbcTemplate template;
public void setTemplate(JdbcTemplate template) {
this.template = template;
}
public List<Employee> getAllEmployees(){
return template.query("select * from employee",new ResultSetExtractor<List<Employee>>(){
#Override
public List<Employee> extractData(ResultSet rs) throws SQLException,
DataAccessException {
List<Employee> list=new ArrayList<Employee>();
while(rs.next()){
Employee e=new Employee();
e.setId(rs.getInt(1));
e.setName(rs.getString(2));
e.setSalary(rs.getInt(3));
list.add(e);
}
return list;
}
});
}
}
Test.java
public class Test {
public static void main(String[] args) {
ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext2.xml");
EmployeeDao dao=(EmployeeDao)ctx.getBean("edao");
List<Employee> list=dao.getAllEmployees();
for(Employee e:list)
System.out.println(e);
}
}
and applicationContext2.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="ds" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://loclahost:3306/test1" />
<property name="username" value="root" />
<property name="password" value="" />
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="ds"></property>
</bean>
<bean id="edao" class="org.resultset.EmployeeDao">
<property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean>
</beans>
These all are java files I am using. It says the setter's return type doesn't match with the getter's, but I checked it, and it is correct there.
The problem is in
<bean id="edao" class="org.resultset.EmployeeDao">
<property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean>
Try changing the name="jdbcTemplate" to name="template". Since you have given name as jdbcTemplate spring will search for a setter method with name setJdbcTemplate() in EmployeeDao class, but the acutal method you have is setTemplate()
Controller extends MethodNameResolver
public final void setMethodNameResolver(
MethodNameResolver methodNameResolver) {
this.methodNameResolver = methodNameResolver;
}
public final MethodNameResolver getMethodNameResolver() {
return this.methodNameResolver;
}
remove spring Annotation like #controller #AutoWired

XML binding with the use of JAXB and Spring-MVC

the following xml is in a repository on a server:
<author xmlns="http://www..." xmlns:atom="http://www.w3.org/2005/atom">
<name>S. Crocker</name>
<address>None</address>
<affiliation></affiliation>
<email>None</email>
</author>
My model class:
#XmlRootElement(name = "author", namespace="http://www...")
#XmlAccessorType(XmlAccessType.FIELD)
public class Author {
#XmlAttribute(name="author")
private String author;
#XmlElement(name="name")
private String name;
#XmlElement(name="address")
private String address;
#XmlElement(name="affiliation")
private String affiliation;
#XmlElement(name="email")
private String email;
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getAffiliation() {
return affiliation;
}
public void setAffiliation(String affiliation) {
this.affiliation = affiliation;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
According to a tutorial i saw i should use the #XmlSchema to a package-info.java
I create a class package-info.java but i don't know how to treat this.
Actually my problem is that i don't know how to use the corect annotations to bind the xml with the model class. The whole story is that i'm trying to retrieve an XML document from a repository, but i take null values. The problem as i saw here: JAXB: How to bind element with namespace
is that i don't use the correct annotations. Does anyone knows which are the correct annotations and how should i use them?
Below is an example of how you could map this use case:
package-info
I would use the package level #XmlSchema annotation to specify the namespace qualification. Specify the namespace to be your target namespace ("http://www.../ckp"). You want this namespace applied to all XML elements so specify elementFormDefault=XmlNsForm.QUALIFIED. The use xmlns to asssociate prefixes with your namespace URIs.
#XmlSchema(
namespace="http://www.../ckp",
elementFormDefault=XmlNsForm.QUALIFIED,
xmlns={
#XmlNs(prefix="", namespaceURI="http://www.../ckp"),
#XmlNs(prefix="atom", namespaceURI="http://www.w3.org/2005/atom"),
}
)
package forum10388261;
import javax.xml.bind.annotation.*;
Author
Below is what your Author class would look like. I have removed the unnecessary annotations (annotations that were equivalent to the default mapping).
package forum10388261;
import javax.xml.bind.annotation.*;
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
public class Author {
#XmlAttribute
private String author;
private String name;
private String address;
private String affiliation;
private String email;
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getAffiliation() {
return affiliation;
}
public void setAffiliation(String affiliation) {
this.affiliation = affiliation;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
Demo
package forum10388261;
import java.io.File;
import javax.xml.bind.*;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Author.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
File xml = new File("src/forum10388261/input.xml");
Author author = (Author) unmarshaller.unmarshal(xml);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(author, System.out);
}
}
Output
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<author xmlns:atom="http://www.w3.org/2005/atom" xmlns="http://www.../ckp">
<name>S. Crocker</name>
<address>None</address>
<affiliation></affiliation>
<email>None</email>
</author>
For More Information
http://blog.bdoughan.com/2010/08/jaxb-namespaces.html
http://blog.bdoughan.com/2011/11/jaxb-and-namespace-prefixes.html
I've never needed to use the namespace parameter on #XmlRootElement, try leaving that off; also, you have #XmlAttribute specified for author, but there's no author in your example besides the tag name.
As for:
Actually my problem is that i don't know how to use the corect
annotations to bind the xml with the model class.
In your spring config you can do:
<oxm:jaxb2-marshaller id="jaxb2Marshaller">
<oxm:class-to-be-bound name="com.mycompany.Author"/>
<!-- ... -->
</oxm:jaxb2-marshaller>
Then inject the jaxb2Marshaller directly or use a MessageConverter like so:
<bean id="xmlConverter" class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter">
<constructor-arg>
<ref bean="jaxb2Marshaller"/>
</constructor-arg>
<property name="supportedMediaTypes">
<list>
<bean class="org.springframework.http.MediaType">
<constructor-arg index="0" value="application"/>
<constructor-arg index="1" value="xml"/>
<constructor-arg index="2" value="UTF-8"/>
</bean>
</list>
</property>
</bean>
If you want to use spring's content negotiation, you could then use AnnotationMethodHandlerAdapter with the message converter:
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>
<ref bean="xmlConverter"/>
<!-- other converters if you have them, e.g. for JSON -->
</list>
</property>
</bean>

Categories

Resources