Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'std' defined in file - spring

package com.nareshit.beans;
public class Address {
private String city,state;
public String toString()
{
return "\n city:"+city+"\nstate:"+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;
}
}
package com.nareshit.clients;
import java.awt.Container;
import java.beans.Beans;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import com.nareshit.beans.Student;
public class Test {
public static void main(String[] args)
{
BeanFactory factory=new XmlBeanFactory(new ClassPathResource("MyBeans.xml"));
Student std1=(Student)factory.getBean("std");
std1.getStudentDetails();
}
}
package com.nareshit.beans;
public class Student {
private int sid;
private String name;
private String address;
public void getStudentDetails()
{
System.out.println("student id:"+sid);
System.out.println("student name:"+name);
System.out.println("student address:"+address);
}
public int getSid() {
return sid;
}
public void setSid(int sid) {
this.sid = sid;
}
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;
}
}
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN"
"http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
<bean id="std" class="com.nareshit.beans.Student">
<property name="std" value="1001"/>
<property name="name" value="mitu"/>
<property name="address" ref="addressObj"/>
</bean>
<bean id="addressObj" class="com.nareshit.beans.Address">
<property name="city" value="bam"/>
<property name="state" value="odisha"/>
</bean>
</beans>
This is the spring setter injection prog. where i am getting error:
Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'std' defined in file("")
how to solve it?

Please see com.nareshit.beans.Student class. It is having one property named as address which is a type of String. When you are writing the XML,
you are giving one reference type of com.nareshit.beans.Address.
Solution :
1. You can give a String value in the XML for address property.like
ddress property like
<bean id="std" class="com.nareshit.beans.Student">
<property name="std" value="1001"/>
<property name="name" value="mitu"/>
<property name="address" value="SOME ADDRESS"/>
</bean>
2. You can change the type of address property in Student Class like
public class Student{
Address address;
//declaration of rest property
//Some Boiler Plate Code
}

Related

Setter Dependency Injection with Array of String

To test the setter dependency injection with an Array of string, I wrote the below-given code -
Pojo class is -
package com.abhishek.ioc.array;
public class Person {
private int id;
private String name;
private String[] hobbies;
public void showHobbies() {
System.out.println("Person name is - "+name+", id is - "+id);
for (int i = 0; i < hobbies.length; i++) {
System.out.println(hobbies[i]);
}
}
public void setId(int id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setHobbies(String[] hobbies) {
this.hobbies = hobbies;
}
}
spring.xml file is -
<beans>
<bean id="person" class="com.abhishek.ioc.array.Person">
<property name="id" value="1"></property>
<property name="name" value="Abhisshek"></property>
<property name="hobbies">
<set>
<value>Playing cricket</value>
<value>Coding</value>
<value>Reading books</value>
</set>
</property>
</bean>
</beans>
Client code is -
package com.abhishek.ioc.array;
public class Client {
public static void main(String[] args) {
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("resources/spring.xml");
System.out.println("Creating Person object");
Person person = (Person)applicationContext.getBean("person");
System.out.println("Person object created");
person.showHobbies();
}
}
In spring.xml file, I tried tags <array>, <list> and <set> to inject data in array and all three tags are giving the correct result. How?

Spring JDBC update without commit

I have a simple table "employee" defined as:
create table employee (id int, name varchar2(40));
I want to write an application to insert values in it and commit only after all values are inserted. Here is my code:
Employee.java:
package com.empl;
public class Employee {
private int id;
private String name;
public void setId(int id) {
this.id = id;
}
public int getId() {
return id;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
EmployeeDAO.java:
package com.empl;
import javax.sql.DataSource;
public interface EmployeeDAO {
public void setDataSource(DataSource dataSource);
public void create(int id, String name);
}
EmployeeJDBCTemplate.java:
package com.empl;
import javax.sql.DataSource;
import org.springframework.jdbc.core.JdbcTemplate;
public class EmployeeJDBCTemplate {
private DataSource dataSource;
private JdbcTemplate jdbcTemplateObject;
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
this.jdbcTemplateObject = new JdbcTemplate(dataSource);
}
public DataSource getDataSource() {
return dataSource;
}
public void create(int id, String name) {
String SQL = "insert into employee (id, name) values (?, ?)";
jdbcTemplateObject.update(SQL, id, name);
}
}
MainApp.java:
package com.empl;
import java.sql.SQLException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
public static void main(String args[]) throws SQLException {
ApplicationContext context = new
ClassPathXmlApplicationContext("Beans.xml");
EmployeeJDBCTemplate employeeJDBCTemplate =
(EmployeeJDBCTemplate) context.getBean("employeeJDBCTemplate");
employeeJDBCTemplate.getDataSource().getConnection().
setAutoCommit(false);
employeeJDBCTemplate.create(1, "E1");
employeeJDBCTemplate.create(2, "E2");
}
}
Beans.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-3.0.xsd ">
<bean id = "dataSource" class =
"org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name = "driverClassName" value =
"oracle.jdbc.driver.OracleDriver"></property>
<property name = "url" value =
"jdbc:oracle:thin:#localhost:1521/xe"></property>
<property name = "username" value = "sys as sysdba"></property>
<property name = "password" value = "pass"></property>
</bean>
<bean id = "employeeJDBCTemplate" class =
"com.empl.EmployeeJDBCTemplate">
<property name = "dataSource" ref = "dataSource"></property>
</bean>
</beans>
I executed the code but when I enter SQLPlus and type the rollback; command, the records are still in the table.
I saw related questions but nothing seems to work.

Autowire based on a condition when xml bean configuration is used

I am working on Spring auto wiring using spring configuration file(xml configuration). I want to inject beans based on a condition.
Let me go into details.
There are two classes 'EmailSender' and 'SmsSender' which implement the interface IMessageSender. Beans are configured for both classes in the configurations file.
I have another class SenderUser which has a instance variable of type IMessageSender in it.
package org.pradeep.core;
public class SenderUser {
private String name;
private String Type;
private IMessageSender msg;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return Type;
}
public void setType(String type) {
Type = type;
}
public IMessageSender getMsg() {
return msg;
}
public void setMsg(IMessageSender msg) {
this.msg = msg;
}
}
I want to inject IMessageSender into bean of SenderUser based on the value of SenderUser.getType(). That means first SernderUser.type should be set and then based on it's value (if value is 'email' then bean with the name 'email' should be wired else bean with the name 'sms' should be wired.) msg should be wired.
Please help me resolve the issue.
I believe the best approach is to implement a BeanFactory for SenderUser. Take a look at this post for an idea.
Interfaces can't be injected, they aren't beans/instances.
you may use SPEL
<bean id="user" class="SenderUser" autowire="byType">
<property name="type" value="email"/>
<property name="msg" value="#{type != null && type == 'email' ? email : sms}"/>
</bean>
<bean id="email" class="EmailSender"/>
<bean id="sms" class="SmsSender"/>

Autowiring String property through application context

I want to autowire a String bean as below
<bean id="name" class="java.lang.String" autowire="byName">
<constructor-arg value="Aravind"/>
</bean>
<bean id="employee" class="Employee" autowire="byName"/>
public Class Employee
{
private String name;
public void setName(String name)
{
this.name=name;
}
public String getName()
{
return name;
}
}
When I try to access the name attribute in the employee is null
Employee emp=(Employee)getApplicationContext().getBean("employee");
System.out.println(emp.getName()==null);
It prints true.
Can someone help on this?
You still need to set the property on the Employee somehow.
Setting the name can be done in multiple ways.
XML configuration.
<bean id="employee" class="Employee" autowire="byName">
<property name="name">
<ref bean="name" />
</property>
</bean>
Using #Autowired
public Class Employee {
#Autowired
private String name;
public void setName(String name) {
this.name=name;
}
public String getName() {
return name;
}
}

Where I did wrong? Why PropertEditorSupport is not working for me?

Why I am getting action in PropertyEditorSupport? Could anyone please help me here because i am new in Spring. Below is the error report
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'cont' defined in class path resource [propertyEdit.xml]: Initialization of bean failed; nested exception is org.springframework.beans.TypeMismatchException: Failed to convert property value of type [java.lang.String] to required type [Phone] for property 'phone'; nested exception is java.lang.IllegalArgumentException: 888-555-1212
Caused by: org.springframework.beans.TypeMismatchException: Failed to convert property value of type [java.lang.String] to required type [Phone] for property 'phone'; nested
exception is java.lang.IllegalArgumentException: 888-555-1212
Caused by: java.lang.IllegalArgumentException: 888-555-1212
at java.beans.PropertyEditorSupport.setAsText(Unknown Source)
at org.springframework.beans.TypeConverterDelegate.doConvertTextValue(TypeConverterDelegate.java:326)
at org.springframework.beans.TypeConverterDelegate.doConvertValue(TypeConverterDelegate.java:305)
at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:192)
at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:138)
at org.springframework.beans.BeanWrapperImpl.convertForProperty(BeanWrapperImpl.java:380)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1111)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:861)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:421)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:251)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:156)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:248)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:160)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:287)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:352)
at org.springframework.context.support.ClassPathXmlApplicationContext.(ClassPathXmlApplicationContext.java:91)
at org.springframework.context.support.ClassPathXmlApplicationContext.(ClassPathXmlApplicationContext.java:75)
at org.springframework.context.support.ClassPathXmlApplicationContext.(ClassPathXmlApplicationContext.java:65)
at ShowContact.main(ShowContact.java:9)
I have used java.beans.PropertyEditorSupport in below way
public class PhoneEditor extends java.beans.PropertyEditorSupport{
public void setAsTest(String textValue)
{
String stripped = stripNonNumeric(textValue);
String areaCode=stripped.substring(0,3);
String prefix=stripped.substring(3,6);
String number=stripped.substring(6);
Phone phone=new Phone(areaCode,prefix,number);
setValue(phone);
}
private String stripNonNumeric(String original)
{
StringBuffer allNumeric = new StringBuffer();
for(int i=0; i<original.length(); i++)
{
char c=original.charAt(i);
if(Character.isDigit(c))
{
allNumeric.append(c);
}
}
return allNumeric.toString();
}
}
My Config file is below
<bean name="customEditorConfigurer" class="org.springframework.beans.factory.config.CustomEditorConfigurer">
<property name="customEditors">
<map>
<entry key="Phone">
<bean id="Phone" class="PhoneEditor">
</bean>
</entry>
</map>
</property>
</bean>
<bean id="cont" class="Contact">
<property name="name" value="Dhirendra"/>
<property name="phone" value="888-555-1212" />
</bean>
</beans>
Phone Class is below
public class Phone {
private String areaCode;
private String prefix;
private String number;
public Phone(){}
public Phone(String areaCode, String prefix, String number)
{
this.areaCode=areaCode;
this.prefix=prefix;
this.number=number;
}
public String getPhoneNumber()
{
return prefix+"-"+areaCode+"-"+number;
}
}
I am calling in the below way
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.beans.factory.config.CustomEditorConfigurer;
public class ShowContact {
public static void main(String[] args)
{
ApplicationContext context = new ClassPathXmlApplicationContext("propertyEdit.xml");
Employee employee=(Employee)context.getBean("cont");
employee.PrintEmpDetails();
}
}
Below is my Contact class which is calling
public class Contact implements Employee {
private Phone phone;
private String name;
public void setPhone(Phone phone) {
// TODO Auto-generated method stub
this.phone=phone;
}
public void setName(String name) {
// TODO Auto-generated method stub
this.name=name;
}
public void PrintEmpDetails()
{
System.out.println("Name of Employee :"+ name);
System.out.println("Contact Number of Employee :"+ phone.getPhoneNumber());
}
}
In PhoneEditor, you've implemented setAsTest, rather than overriding setAsText. As a result, Spring is calling the setAsText implementation in PropertyEditorSupport, which throws the exception.
This is why you should always use #Override annotations, and set your compiler to at least report a warning if you don't do it.
The problem is that you have a typo in your class. It's setAsText, not setAsTest:
#Override
public void setAsText(String textValue) throws IllegalArgumentException {
final String stripped = stripNonNumeric(textValue);
final String areaCode=stripped.substring(0,3);
final String prefix=stripped.substring(3,6);
final String number=stripped.substring(6);
final Phone phone=new Phone(areaCode,prefix,number);
setValue(phone);
}
(always use #Override, as skaffman suggested)

Resources