Using aggregation with Spring JDBC - java

I am learning Spring JDBC inserting to database but I could not insert my 2 aggregated classes together. (Employee which has Address class). How can I add Address class' variables to Employee table? Code below, thanks.
Employee.java
package model;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
public class Employee {
private int id;
private String name;
private String surname;
private int age;
private String gender;
private String contact;
public Employee(int id, String name, String surname, int age, String gender, String contact, Address address) {
super();
this.id = id;
this.name = name;
this.surname = surname;
this.age = age;
this.gender = gender;
this.contact = contact;
this.address = address;
}
private Address address;
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 String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getContact() {
return contact;
}
public void setContact(String contact) {
this.contact = contact;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
#Override
public String toString() {
return "Employee [id=" + id + ", name=" + name + ", surname=" + surname + ", age=" + age + ", gender=" + gender
+ ", contact=" + contact + ", address=" + address + "]";
}
}
Address.java
package model;
public class Address {
private String address;
private String city;
private String country;
public Address(String address, String city, String country) {
super();
this.address = address;
this.city = city;
this.country = country;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
#Override
public String toString() {
return "[" + address + ", city=" + city + ", country=" + country + "]";
}
}
EmployeeDAO.java
package dao;
import java.sql.SQLException;
import model.Employee;
public interface EmployeeDAO {
public void saveEmployee(Employee employee) throws Exception;
}
EmployeeDAOImpl.java
package dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import javax.sql.DataSource;
import org.springframework.stereotype.Repository;
import model.Employee;
public class EmployeeDAOImpl implements EmployeeDAO {
private final static String INSERT_EMPLOYEE = "insert into employee (id, name, surname, age, gender, contact) values (?,?,?,?,?,?)";
private DataSource dataSource;
public DataSource getDataSource() {
return dataSource;
}
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
#Override
public void saveEmployee(Employee employee) throws SQLException {
try {
Connection connection = dataSource.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement(INSERT_EMPLOYEE);
preparedStatement.setInt(1, employee.getId());
preparedStatement.setString(2, employee.getName());
preparedStatement.setString(3, employee.getSurname());
preparedStatement.setInt(4, employee.getAge());
preparedStatement.setString(5, employee.getGender());
preparedStatement.setString(6, employee.getContact());
//index 7,8 and 9 are address, city and country...
preparedStatement.executeUpdate();
preparedStatement.close();
System.out.println("Employee is inserted..." + employee);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
xml file
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd ">
<bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>myconfiguration/jdbc.properties</value>
</property>
</bean>
<bean id="dataSourceId"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<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>
<bean id="employeeDAOImplId" class="dao.EmployeeDAOImpl">
<property name="dataSource" ref="dataSourceId" />
</bean>
</beans>
MainTest.java
package test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import dao.EmployeeDAO;
import model.Employee;
public class MainTest {
public static void main(String[] args) throws Exception {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("EmployeeJDBC.xml");
EmployeeDAO dao = context.getBean(EmployeeDAO.class);
Employee employee = new Employee(1, "John", "Doe", 24, "M", "+15555555555", null); // here null, i couldn't fix.
// Address address = new Address("RandAddress", "RandCity", "RandCountry");
dao.saveEmployee(employee);
}
}

By your design, you should be able just to add appropriate columns to the insert query, and update parameters:
// EmployeeDAOImpl
private final static String INSERT_EMPLOYEE = "insert into employee (id, name, surname, age, gender, contact, address, city, country) values (?,?,?,?,?,?,?,?,?)";
// ...
#Override
public void saveEmployee(Employee employee) throws SQLException {
try {
Connection connection = dataSource.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement(INSERT_EMPLOYEE);
preparedStatement.setInt(1, employee.getId());
preparedStatement.setString(2, employee.getName());
preparedStatement.setString(3, employee.getSurname());
preparedStatement.setInt(4, employee.getAge());
preparedStatement.setString(5, employee.getGender());
preparedStatement.setString(6, employee.getContact());
//index 7,8 and 9 are address, city and country...
preparedStatement.setString(7, employee.getAddress().getAddress());
preparedStatement.setString(8, employee.getAddress().getCity());
preparedStatement.setString(9, employee.getAddress().getCountry());
preparedStatement.executeUpdate();
preparedStatement.close();
System.out.println("Employee is inserted..." + employee);
} catch (SQLException e) {
e.printStackTrace();
}
}
And set the fields in MainTest:
public class MainTest {
public static void main(String[] args) throws Exception {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("EmployeeJDBC.xml");
EmployeeDAO dao = context.getBean(EmployeeDAO.class);
Address address = new Address("RandAddress", "RandCity", "RandCountry");
Employee employee = new Employee(1, "John", "Doe", 24, "M", "+15555555555", address);
dao.saveEmployee(employee);
}
}

Related

(error while creating beans ) - org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name studentRepository

I am trying to create a basic web service using JPA. But beans are not being initialised. can anyone help me on this ?
The error:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'studentRepository' defined in com.Spring.DataJPA.StudentRepository defined in #EnableJpaRepositories declared on JpaRepositoriesRegistrar.EnableJpaRepositoriesConfiguration:
Invocation of init method failed; nested exception is
java.lang.IllegalArgumentException: Not a managed type: class com.Spring.Data.Student
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1786)
Student.java
package com.Spring.Data;
import net.bytebuddy.dynamic.loading.InjectionClassLoader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.annotation.Id;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
#Entity
public class Student {
#Id
#GeneratedValue(strategy =GenerationType.AUTO)
private Long id;
private String firstName;
public Long getId() {
return id;
}
private String lastName;
private int age;
private Address address;
public Student(){
}
public Student(String firstName, String lastName, int age, Address address) {
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
this.address = address;
}
public String getFullName() {
return firstName;
}
public void setFullName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
#Override
public String toString() {
return "Student{" +
"fullName='" + firstName + '\'' +
", lastName='" + lastName + '\'' +
", age=" + age +
", address=" + address +
'}';
}
}
Address.java
public class Address {
private String houseNo;
private String city;
private String pincode;
private String landmark;
public Address(){}
public Address(String houseNo, String city, String pincode, String landmark) {
this.houseNo = houseNo;
this.city = city;
this.pincode = pincode;
this.landmark = landmark;
}
public String getHouseNo() {
return houseNo;
}
public void setHouseNo(String houseNo) {
this.houseNo = houseNo;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getPincode() {
return pincode;
}
public void setPincode(String pincode) {
this.pincode = pincode;
}
public String getLandmark() {
return landmark;
}
public void setLandmark(String landmark) {
this.landmark = landmark;
}
#Override
public String toString() {
return "Address{" +
"houseNo='" + houseNo + '\'' +
", city='" + city + '\'' +
", pincode='" + pincode + '\'' +
", landmark='" + landmark + '\'' +
'}';
}
}
StudentRepository.java
import com.Spring.Data.Student;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
public interface StudentRepository extends CrudRepository<Student, Long> {
List<Student> findByPinCode(String pincode);
List<Student> findByName(String lastName);
}
Application.java
package com.Spring.DataJPA;
import com.Spring.Data.Address;
import com.Spring.Data.Student;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
#SpringBootApplication
public class DataJpaApplication {
private static final Logger log = LoggerFactory.getLogger(DataJpaApplication.class);
public static void main(String[] args) {
SpringApplication.run(DataJpaApplication.class, args);
}
#Bean
public CommandLineRunner runner(StudentRepository repository){
return (args) -> {
Address address0 = new Address(
"3-14-5","Tuni","533401","MR Peta"
);
Student student0 = new Student(
"Anjaneya",
"varma",
24,
address0
);
Address address1 = new Address(
"3-14-5","Tuni","533402","MR Peta"
);
Student student1 = new Student(
"Tirupathi",
"Raju",
50,
address1
);
repository.save(student0);
repository.save(student1);
log.info("Students found with findAll():");
log.info("-------------------------------");
for(Student student: repository.findAll()){
log.info(student.toString());
}
log.info("");
};
}
}
This errors occurs because spring isn't reading the package that your enity is.Try to use on your SpringConfig :
#EntityScan("your.base.package.*")

custom converter not called spring data mongodb [can't serialize class error]

I have a User bean with a property address. I have implemented custom converter for the User and the Address class and configured the same in spring XML. The converter for User is getting called every time I save User object. But, converter for Address is not getting called while saving the User and it throwing can't serialize class com.mkyong.model.Address.
Here is my class structure and Xml config:
User Class:
package com.mkyong.model;
import java.util.Map;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
#Document(collection = "person")
public class User {
#Id
private String id;
String username;
String password;
Address address;
Map data;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public Map getData() {
return data;
}
public void setData(Map data) {
this.data = data;
}
public User(String username, String password) {
super();
this.username = username;
this.password = password;
}
#Override
public String toString() {
return "User [id=" + id + ", username=" + username + ", password=" + password + "]";
}
}
Address class :
package com.mkyong.model;
import java.io.Serializable;
import org.springframework.data.mongodb.core.mapping.Document;
#Document(collection = "address")
public class Address implements Serializable {
/**
*
*/
private static final long serialVersionUID = 2310280839505243479L;
String city;
String dist;
String state;
public Address(String city, String dist, String state) {
super();
this.city = city;
this.dist = dist;
this.state = state;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getDist() {
return dist;
}
public void setDist(String dist) {
this.dist = dist;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
#Override
public String toString() {
return "Address [city=" + city + ", dist=" + dist + ", state=" + state + "]";
}
}
spring configuration:
<mongo:mongo host="127.0.0.1" port="27017" />
<mongo:db-factory dbname="springbootdb" />
<mongo:mapping-converter id="mongoConverter">
<mongo:custom-converters base-package="com.mkyong.model">
<mongo:converter>
<bean class="com.mkyong.converter.UserConverter" />
</mongo:converter>
<mongo:converter>
<bean class="com.mkyong.converter.AddressConverter" />
</mongo:converter>
</mongo:custom-converters>
</mongo:mapping-converter>
<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
<constructor-arg name="mongoConverter" ref="mongoConverter" />
<constructor-arg name="mongoDbFactory" ref="mongoDbFactory" />
</bean>
User Converter :
package com.mkyong.converter;
import org.springframework.core.convert.converter.Converter;
import com.mkyong.model.User;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
public class UserConverter implements Converter<User, DBObject> {
#Override
public DBObject convert(User user) {
DBObject dbObject = new BasicDBObject();
dbObject.put("_id", user.getId());
dbObject.put("_address", user.getAddress());
System.out.println("called !!!!!");
return dbObject;
}
}
Address Converter :
package com.mkyong.converter;
import org.springframework.core.convert.converter.Converter;
import com.mkyong.model.Address;
import com.mkyong.model.DecimalNumber;
import com.mkyong.model.User;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
public class AddressConverter implements Converter<Address, String> {
#Override
public String convert(Address user) {
System.out.println("Not called!!!");
return user==null ? null : user.toString();
}
}
I am very new to spring mongodb. Any help is greatly appreciated!
Please annotate UserConverter with #Component so that your converter will be picked by Spring Container.

Exception in webapp,i.e. org.apache.jasper.JasperException

I have built a dao layer which connects with a derby db with the use of jdbctemplate.
The insert query works fine but when I try to select all rows from the database, the webapp gives me this error:
org.apache.jasper.JasperException: An exception occurred processing
JSP page /WEB-INF/jsp/DisplayEmployee.jsp at line 26
23: 24: 25: 26: ${temp.FirstName} 27:
${temp.MiddleName} 28: ${temp.LastName}
29: ${temp.email}
avax.el.PropertyNotFoundException: Property 'FirstName' not found on
type com.user.EmployeeInfo
Code:
DAO:
public class EmployeeDao {
JdbcTemplate template;
public void setTemplate(JdbcTemplate template) {
this.template = template;
}
public int insert(EmployeeInfo emp){
String sql = "insert into employee VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)";
int i=template.update(sql, emp.getFirstName(), emp.getMiddleName(), emp.getLastName(), emp.getEmail(), emp.getGender(), emp.getDob(), emp.getAddress1(), emp.getAddress2(), emp.getEmpID());
return i;
}
public List<EmployeeInfo> retrieveMultipleRowsColumns(){
String sql = "select * from employee";
//return template.queryForList(sql, elementType)
//List<EmployeeInfo> list = template.query(sql,new BeanPropertyRowMapper<EmployeeInfo>(EmployeeInfo.class));
//List<EmployeeInfo> list2 = template.queryForList(sql, EmployeeInfo.class);
List<EmployeeInfo> list3 = template.query(sql, new RowMapper<EmployeeInfo>(){
public EmployeeInfo mapRow(ResultSet rs, int rownumber) throws SQLException {
EmployeeInfo e = new EmployeeInfo();
e.setFirstName(rs.getString(1));
e.setMiddleName(rs.getString(2));
e.setLastName(rs.getString(3));
e.setEmail(rs.getString(4));
e.setGender(rs.getString(5));
e.setDob(rs.getDate(6));
e.setAddress1(rs.getString(7));
e.setAddress2(rs.getString(8));
e.setEmpID(rs.getInt(9));
return e;
}
});
return list3;
}
Controller:
public class EmployeeAddition {
#Autowired
EmployeeDao dao;
#RequestMapping("/addresult")
public ModelAndView addResult(HttpServletRequest req,HttpServletResponse res) {
String fname = req.getParameter("FirstName");
String mname = req.getParameter("MiddleName");
String middlename;
if(mname!="null"&&mname.trim()!=""){
middlename=mname;
}
else
{
middlename="-";
}
String lname = req.getParameter("LastName");
String empid = req.getParameter("empID");
int empID = Integer.parseInt(empid);
String email = req.getParameter("Email");
String gender = req.getParameter("gender");
Date dob = Date.valueOf(req.getParameter("DOB"));
String addr1 = req.getParameter("address1");
String addr2 = req.getParameter("address2");
EmployeeInfo emp = new EmployeeInfo(fname,middlename,lname,email,gender,dob,addr1,addr2,empID);
int ret = dao.insert(emp);
if(ret==0){
return new ModelAndView("EmployeeAddResult","mess","Success");
}
else
{
return new ModelAndView("EmployeeAddResult","mess","hi");
}
}
#RequestMapping("/display")
public ModelAndView viewEmployee(HttpServletRequest req,HttpServletResponse res,ModelMap model) {
List<EmployeeInfo> list=dao.retrieveMultipleRowsColumns();
model.put("list",list);
return new ModelAndView("DisplayEmployee","mess","Welcome "+(String)req.getSession().getAttribute("uname"));
}
}
The jsp where i'm displaying the result:
<div class="right_disp left">
<c:forEach items="${list}" var="temp">
<tr>
<td>${temp.FirstName}</td>
<td>${temp.MiddleName}</td>
<td>${temp.LastName}</td>
<td>${temp.email}</td>
<td>${temp.gender}</td>
<td>${temp.dob}</td>
<td>${temp.Address1}</td>
<td>${temp.Address2}</td>
<td>${temp.empID}</td>
</tr>
</c:forEach>
</div>
The variable name match the original variables of the POJO class but I don't understand why the error for Property not found on the class is coming.
Appreciate any suggestion or help.
Edit:
EmployeeInfo class(POJO)
import java.sql.Date;
public class EmployeeInfo {
String FirstName;
String MiddleName;
String LastName;
String email;
String gender;
Date dob;
String Address1;
String Address2;
int empID;
public EmployeeInfo(){
}
public EmployeeInfo(String firstName, String middleName, String lastName, String email, String gender,
Date dob, String address1, String address2, int empID) {
super();
FirstName = firstName;
MiddleName = middleName;
LastName = lastName;
this.email = email;
this.gender = gender;
this.dob = dob;
Address1 = address1;
Address2 = address2;
this.empID = empID;
}
public String getFirstName() {
return FirstName;
}
public void setFirstName(String firstName) {
FirstName = firstName;
}
public String getMiddleName() {
return MiddleName;
}
public void setMiddleName(String middleName) {
MiddleName = middleName;
}
public String getLastName() {
return LastName;
}
public void setLastName(String lastName) {
LastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public Date getDob() {
return dob;
}
public void setDob(Date dob) {
this.dob = dob;
}
public String getAddress1() {
return Address1;
}
public void setAddress1(String address1) {
Address1 = address1;
}
public String getAddress2() {
return Address2;
}
public void setAddress2(String address2) {
Address2 = address2;
}
public int getEmpID() {
return empID;
}
public void setEmpID(int empID) {
this.empID = empID;
}
}
Don't capitalise the first letter of the property names if they follow the bean properties naming convention.
If your getter and setter are named getSomeProperty and setSomeProperty then in a template you should use someProperty not SomeProperty.
Your naming conventions are the issue. try to stick with some convention across the board (for eg: camel casing)
<td>${temp.FirstName}</td>
try updating to
<td>${temp.firstName}</td>

How to customise an XML export using JAXB

For testing purposes, I used used JAXB to generate an XML from an Object. This work fine. The code is below.
package com.mns.mnsutilities.jaxb.model;
import java.util.List;
import javax.xml.bind.annotation.*;
#XmlRootElement(name="Emp_MNS")
#XmlType(propOrder= {"name", "age", "role", "gender", "addressesList"})
public class Employee {
private int id;
private String gender;
private int age;
private String name;
private String role;
private String password;
private List<Address> addressesList;
public Employee() {}
public Employee(int id, String gender, int age, String name, String role,
String password) {
super();
this.id = id;
this.gender = gender;
this.age = age;
this.name = name;
this.role = role;
this.password = password;
}
public Employee(int id, String gender, int age, String name, String role,
String password, List<Address> addressesList) {
super();
this.id = id;
this.gender = gender;
this.age = age;
this.name = name;
this.role = role;
this.password = password;
this.addressesList = addressesList;
}
#XmlAttribute
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
#XmlElement(name = "gen")
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
// #XmlNullPolicy(emptyNodeRepresentsNull = true, nullRepresentationForXml = XmlMarshalNullRepresentation.EMPTY_NODE)
#XmlElement(nillable=true)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
#XmlTransient
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
#XmlElement(name = "addresses")
public List<Address> getAddressesList() {
return addressesList;
}
public void setAddressesList(List<Address> addressesList) {
this.addressesList = addressesList;
}
#Override
public String toString() {
return "Employee [id=" + id + ", gender=" + gender + ", age=" + age
+ ", name=" + name + ", role=" + role + ", password="
+ password + ", addressesList=" + addressesList + "]";
}
}
And:
package com.mns.mnsutilities.jaxb.model;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement(namespace="")
public class Address {
private String street;
private String city;
private String zipCode;
private String country;
public Address() {}
public Address(String street, String city, String zipCode, String country) {
super();
this.street = street;
this.city = city;
this.zipCode = zipCode;
this.country = country;
}
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getZipCode() {
return zipCode;
}
public void setZipCode(String zipCode) {
this.zipCode = zipCode;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
#Override
public String toString() {
return "Address [street=" + street + ", city=" + city + ", zipCode="
+ zipCode + ", country=" + country + "]";
}
}
My main Class is :
package com.mns.mnsutilities.jaxb.batch;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import com.mns.mnsutilities.jaxb.model.Address;
import com.mns.mnsutilities.jaxb.model.Employee;
public class LaunchAction {
private static final String FILE_NAME = "output/CT3D_XML_SAMPLE_FINAL.xml";
public static void main(String[] args) {
Employee emp = new Employee();
emp.setId(1);
emp.setAge(25);
emp.setName("Yovan");
emp.setGender("Male");
emp.setRole("Developer");
emp.setPassword("sensitive");
List<Address> addressesList = new ArrayList<>();
Address address1 = new Address("Main Road", "Ebene", "11111", "Mauritius");
Address address2 = new Address("Royal Road", "Rose-Hill", "2222", "Mauritius");
addressesList.add(address1);
addressesList.add(address2);
emp.setAddressesList(addressesList);
jaxbObjectToXML(emp);
Employee empFromFile = jaxbXMLToObject();
System.out.println(empFromFile.toString());
}
private static Employee jaxbXMLToObject() {
try {
JAXBContext context = JAXBContext.newInstance(Employee.class);
Unmarshaller un = context.createUnmarshaller();
Employee emp = (Employee) un.unmarshal(new File(FILE_NAME));
return emp;
} catch (JAXBException e) {
e.printStackTrace();
}
return null;
}
private static void jaxbObjectToXML(Employee emp) {
try {
JAXBContext context = JAXBContext.newInstance(Employee.class);
Marshaller m = context.createMarshaller();
//for pretty-print XML in JAXB
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
// Write to System.out for debugging
m.marshal(emp, System.out);
// Write to File
m.marshal(emp, new File(FILE_NAME));
} catch (JAXBException e) {
e.printStackTrace();
}
}
}
The XML output is :
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Emp_MNS id="1">
<name xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true">
</name>
<age>25</age>
<role>Developer</role>
<gen>Juggoo</gen>
<addresses>
<city>Ebene</city>
<country>Mauritius</country>
<street>Main Road</street>
<zipCode>11111</zipCode>
</addresses>
<addresses>
<city>Rose-Hill</city>
<country>Mauritius</country>
<street>Royal Road</street>
<zipCode>2222</zipCode>
</addresses>
</Emp_MNS>
What I really would like to have is :
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Emp_MNS id="1">
<name xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true">
</name>
<age>25</age>
<role>Developer</role>
<gen>Juggoo</gen>
<addresses>
**<address>**
<city>Ebene</city>
<country>Mauritius</country>
<street>Main Road</street>
<zipCode>11111</zipCode>
**</address>**
**<address>**
<city>Rose-Hill</city>
<country>Mauritius</country>
<street>Royal Road</street>
<zipCode>2222</zipCode>
**</address>**
</addresses>
</Emp_MNS>
Could you please guide me on how to proceed?
You can do the following:
#XmlElementWrapper(name="addresses")
#XmlElement(name="address")
public List<Address> getAddressesList() {

JAXB - Prevent nillable attributes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"

Here is my problem: I need the name tag of by object to be present in the XML but without the nillable attributes : In short like <name/>. Here is the code for the object.
If name is null, I do get the tag <name xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>, but the additional attributes may cause problem to the client.
As I have read, semantically it does make sense to represent the null values this way (using #XmlElement(nillable=true)).
package com.mns.mnsutilities.jaxb.model;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.XmlType;
#XmlRootElement(name="Emp_MNS")
#XmlType(propOrder= {"name", "age", "role", "gender", "addressesList"})
public class Employee {
private int id;
private String gender;
private int age;
private String name;
private String role;
private String password;
private List<Address> addressesList;
public Employee() {}
public Employee(int id, String gender, int age, String name, String role,
String password) {
super();
this.id = id;
this.gender = gender;
this.age = age;
this.name = name;
this.role = role;
this.password = password;
}
public Employee(int id, String gender, int age, String name, String role,
String password, List<Address> addressesList) {
super();
this.id = id;
this.gender = gender;
this.age = age;
this.name = name;
this.role = role;
this.password = password;
this.addressesList = addressesList;
}
#XmlAttribute
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
#XmlElement(name = "gen", nillable=true)
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
#XmlElement(nillable=true)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
#XmlTransient
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
#XmlElementWrapper( name="addresses" )
#XmlElement(name = "address")
public List<Address> getAddressesList() {
if(addressesList == null){
addressesList = new ArrayList<>();
}
return addressesList;
}
public void setAddressesList(List<Address> addressesList) {
this.addressesList = addressesList;
}
#Override
public String toString() {
return "Employee [id=" + id + ", gender=" + gender + ", age=" + age
+ ", name=" + name + ", role=" + role + ", password="
+ password + ", addressesList=" + addressesList + "]";
}
}
Expanding on the comment made by Ian Roberts you could leverage field access and have the property treat a field value of "" as null.
#XmlRootElement(name="Emp_MNS")
#XmlAccessorType(XmlAccessType.FIELD)
public class Employee {
private String name = "";
public String getName() {
if(name.length() == 0) {
return null;
}
return name;
}
public void setName(String name) {
if(null == name) {
this.name = "";
} else {
this.name = name;
}
}
i got the same problem,But my field is enum,It can't be emyty string;so I just use
myXml.replaceAll("xsi:nil=\"true\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"","")
in another solution,I add a empty string value to my enum,such as
#XmlEnum
#Getter
public enum MyEnum {
#XmlEnumValue("1") Apple("1"),
#XmlEnumValue("2") Banner("2"),
#XmlEnumValue("") NULL("3");
MyEnum(String value, String description) {
this.value = value;
this.description = description;
}
private String value;
private String description;
}
so that I can set MyEnum.NULL to filed;

Categories

Resources