Are annotations must to Serailaize the java object via JaxB? - java

Sometimes it serializes without annotations in xml and the other times it doesnt?Someone please enlighten me regarding the necessity of Annotations.
#XmlRootElement
public class Test {
public void setAge(int age) {
this.age = age;
}
private int age;
private String name;
private Cat cat;
public Test()
{
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public Cat getCat() {
return cat;
}
public void setCat(Cat cat) {
this.cat = cat;
}
}
class Cat
{
private String name="catttttttttttttttt";
public Cat()
{
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
In the above code,it works fine,but sometimes if dont add #XMLElement above the getCat(),it doesnt serialize.

I googled through some sites and got the best explanation here:
http://blog.bdoughan.com/2011/06/using-jaxbs-xmlaccessortype-to.html
Its not required to put annotations and it depends completely on #XmlAccessorType.
Thanq
public class MainClass {
public static void main(String[] args) throws Exception {
JAXBContext contextObj = JAXBContext.newInstance(Test.class);
Marshaller marshallerObj = contextObj.createMarshaller();
marshallerObj.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
Test test = new Test();test.setAge(25);test.setName("Sriharsha");test.setCat(new Cat());
marshallerObj.marshal(test, new FileOutputStream("/home/pankaj/Downloads/Emp.xml"));
System.out.println();
}
}

Related

Adding test in JUnit that fails if Serialized Object changes

I have the following class that is created with the usage of a builder:
public class Foo {
private String name;
private int age;
public String getName() { return name; }
public int getAge() { return age; }
private Foo(Builder b) {
name = b.name;
age = b.age;
}
public static final class Builder {
private String name;
private int age;
public Builder name(String name) {
this.name = name;
return this;
}
public Builder age(int age) {
this.age = age;
return this;
}
}
}
Now I want to add a JUnit test for this where if this class were to change (via new field were to be added, some other changes made to this) that would also be reflected once the class got serialized, I want that test to fail to catch that change. I am not aware of any libraries that can do this, how can this be done?

Complex Java Object to Json

I have a java class like :
public class Sclass {
private Student student;
private Teacher teacher;
public Student getStudent() {
return student;
}
public void setStudent(Student student) {
this.student = student;
}
public Teacher getTeacher() {
return teacher;
}
public void setTeacher(Teacher teacher) {
this.teacher = teacher;
}
}
public class Teacher {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class Student {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
I want to use Sclass in a rest service and thus want a json for the same, please assist.
Example using gson:
Student student = new Student();
student.setName("Student 1");
student.setAge(18);
Teacher teacher = new Teacher();
teacher.setName("Teacher 1");
Sclass sclass = new Sclass();
sclass.setStudent(student);
sclass.setTeacher(teacher);
Gson gson = new Gson();
String json = gson.toJson(sclass);
System.out.println(json);
Output:
{"student":{"name":"Student 1","age":18},"teacher":{"name":"Teacher 1"}}

Why hibernate does not write any information in table?

I have such situation:
There are a few groups of POJO classes, each with one parent. Each group serves to be working with some recording of data - to the XML with the help of JAXB and to the database with the help of Hibernate. A simplified version of my working code is:
public static abstract class Habit{
String habitName;
/* constructors */
/* getter & setter */
}
#Entity
#Access(AccessType.PROPERTY)
#Table(name = "habit")
public static class DBHabit extends Habit{
#Id
#GeneratedValue
private int id;
#Column(name = "habit_name")
public String getHabitName() {
return habitName;
}
public void setHabitName(String habitName) {
this.habitName = habitName;
}
}
#XmlAccessorType(XmlAccessType.PROPERTY)
#XmlRootElement(name = "habit")
public static class XmlHabit extends Habit{
#XmlElement
public String getHabitName() {
return habitName;
}
public void setHabitName(String habitName) {
this.habitName = habitName;
}
}
public static abstract class Person{
int age;
String name;
List<Habit> habits;
/* Constructor */
/* Getters & Setters */
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Habit> getHabits() {
return habits;
}
public void setHabits(List<Habit> habits) {
this.habits = habits;
}
}
#Entity
#Access(AccessType.PROPERTY)
#Table(name = "person")
public static class DBPerson extends Person{
#Id
#GeneratedValue
private int id;
#Column(name = "age")
#Override
public int getAge() {
return age;
}
#Override
public void setAge(int age) {
this.age = age;
}
#Column(name = "name")
#Override
public String getName() {
return name;
}
#Override
public void setName(String name) {
this.name = name;
}
#OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL, targetEntity = DBHabit.class)
#Override
public List<Habit> getHabits() {
return habits;
}
#Override
public void setHabits(List<Habit> friends) {
this.habits = habits;
}
}
#XmlAccessorType(XmlAccessType.PROPERTY)
#XmlType(name = "", propOrder = {
"age",
"name",
"habits"
})
#XmlRootElement(name = "state")
public static class XmlPerson extends Person{
#Override
#XmlElement(required = true)
public int getAge() {
return super.getAge();
}
#Override
public void setAge(int age) {
super.setAge(age);
}
#Override
#XmlElement(required = true)
public String getName() {
return super.getName();
}
#Override
public void setName(String name) {
super.setName(name);
}
#Override
#XmlElement(required = true)
#XmlElementWrapper(name = "friends")
public List<Habit> getHabits() {
return super.getHabits();
}
#Override
public void setHabits(List<Habit> habits) {
super.setHabits(habits);
}
}
I have problems with working with Hibernate. Thought I wrote that I expect the recording of DBHabit.class in targetEntity, hibernate does not record any information about habits, this table is always empty.
Please give me a hint, what can I make in such situation or advice, how I can make a similar abstract system like this for the writing in different ways.
Thank you for attention!
A couple of strange thing i noticed in your mapping:
a #OneToOne mapping, backed by a List<Habit>. Why not directly Habit ?
You annotate class with #Access(AccessType.PROPERTY) but then you put the mapping annotation on accessor methods (you're issue might come from there).
Instead you could try to annotate the parent abstract class as #MappedSuperclass. This way, you do not have to redefine the accessor. Or if you do not wish to put hibernate annotations in the parent class, remove the #Access(AccessType.PROPERTY) annotation.

JAXB #XmlIDREF in XmlAdapter for immutable objects

I'm using XmlAdapter for immutable objects as proposed in this blog post: http://blog.bdoughan.com/2010/12/jaxb-and-immutable-objects.html. This works fine, but not with references to other immutable objects in my adapters. Is there any way to handle this with JAXB?
Below there is an example which does not work if the person's xml tag comes after the company's xml tag which references the person.
Immutable objects:
#XmlJavaTypeAdapter(PersonAdapter.class)
public class Person {
private final String id;
private final String name;
public Person(String id, String name) {
this.id = id;
this.name = name;
}
public String getId() {
return id;
}
public String getName() {
return name;
}
}
#XmlJavaTypeAdapter(CompanyAdapter.class)
public class Company {
private final String name;
private final Person principal;
public Company(String name, Person principal) {
this.name = name;
this.principal = principal;
}
public String getName() {
return name;
}
public Person getPrincipal() {
return principal;
}
}
PersonAdapter:
public class PersonAdapter extends XmlAdapter<AdaptedPerson, Person> {
public static class AdaptedPerson {
#XmlID
#XmlAttribute
String id;
#XmlAttribute
String name;
}
#Override
public AdaptedPerson marshal(Person v) throws Exception {
AdaptedPerson a = new AdaptedPerson();
a.id = v.getId();
a.name = v.getName();
return a;
}
#Override
public Person unmarshal(AdaptedPerson v) throws Exception {
return new Person(v.id, v.name);
}
}
CompanyAdapter:
public class CompanyAdapter extends XmlAdapter<AdaptedCompany, Company> {
public static class AdaptedCompany {
#XmlAttribute
String name;
#XmlIDREF
#XmlAttribute
Person principal;
}
#Override
public AdaptedCompany marshal(Company v) throws Exception {
AdaptedCompany a = new AdaptedCompany();
a.name = v.getName();
a.principal = v.getPrincipal();
return a;
}
#Override
public Company unmarshal(AdaptedCompany v) throws Exception {
return new Company(v.name, v.principal);
}
}

SUPER CSV write bean to CSV

Here is my class,
public class FreebasePeopleResults {
public String intendedSearch;
public String weight;
public Double heightMeters;
public Integer age;
public String type;
public String parents;
public String profession;
public String alias;
public String children;
public String siblings;
public String spouse;
public String degree;
public String institution;
public String wikipediaId;
public String guid;
public String id;
public String gender;
public String name;
public String ethnicity;
public String articleText;
public String dob;
public String getWeight() {
return weight;
}
public void setWeight(String weight) {
this.weight = weight;
}
public Double getHeightMeters() {
return heightMeters;
}
public void setHeightMeters(Double heightMeters) {
this.heightMeters = heightMeters;
}
public String getParents() {
return parents;
}
public void setParents(String parents) {
this.parents = parents;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getProfession() {
return profession;
}
public void setProfession(String profession) {
this.profession = profession;
}
public String getAlias() {
return alias;
}
public void setAlias(String alias) {
this.alias = alias;
}
public String getChildren() {
return children;
}
public void setChildren(String children) {
this.children = children;
}
public String getSpouse() {
return spouse;
}
public void setSpouse(String spouse) {
this.spouse = spouse;
}
public String getDegree() {
return degree;
}
public void setDegree(String degree) {
this.degree = degree;
}
public String getInstitution() {
return institution;
}
public void setInstitution(String institution) {
this.institution = institution;
}
public String getWikipediaId() {
return wikipediaId;
}
public void setWikipediaId(String wikipediaId) {
this.wikipediaId = wikipediaId;
}
public String getGuid() {
return guid;
}
public void setGuid(String guid) {
this.guid = guid;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEthnicity() {
return ethnicity;
}
public void setEthnicity(String ethnicity) {
this.ethnicity = ethnicity;
}
public String getArticleText() {
return articleText;
}
public void setArticleText(String articleText) {
this.articleText = articleText;
}
public String getDob() {
return dob;
}
public void setDob(String dob) {
this.dob = dob;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getSiblings() {
return siblings;
}
public void setSiblings(String siblings) {
this.siblings = siblings;
}
public String getIntendedSearch() {
return intendedSearch;
}
public void setIntendedSearch(String intendedSearch) {
this.intendedSearch = intendedSearch;
}
}
Here is my CSV writer method
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import org.supercsv.io.CsvBeanWriter;
import org.supercsv.prefs.CsvPreference;
public class CSVUtils {
public static void writeCSVFromList(ArrayList<FreebasePeopleResults> people, boolean writeHeader) throws IOException{
//String[] header = new String []{"title","acronym","globalId","interfaceId","developer","description","publisher","genre","subGenre","platform","esrb","reviewScore","releaseDate","price","cheatArticleId"};
FileWriter file = new FileWriter("/brian/brian/Documents/people-freebase.csv", true);
// write the partial data
CsvBeanWriter writer = new CsvBeanWriter(file, CsvPreference.EXCEL_PREFERENCE);
for(FreebasePeopleResults person:people){
writer.write(person);
}
writer.close();
// show output
}
}
I keep getting output errors. Here is the error:
There is no content to write for line 2 context: Line: 2 Column: 0 Raw line:
null
Now, I know it is now totally null, so I am confused.
So it's been a while, and you've probably moved on from this, but...
The issue was actually that you weren't supplying the header to the write() method, i.e. it should be
writer.write(person, header);
Unfortunately the API is a little misleading in it's use of the var-args notation in the signature of the write() method, as it allows null to be passed in. The javadoc clearly states that you shouldn't do this, but there was no null-check in the implementation: hence the exception you were getting.
/**
* Write an object
*
* #param source
* at object (bean instance) whose values to extract
* #param nameMapping
* defines the fields of the class that must be written.
* null values are not allowed
* #since 1.0
*/
public void write(Object source, String... nameMapping) throws IOException,
SuperCSVReflectionException;
Super CSV 2.0.0-beta-1 is out now. It retains the var-args in the write() method, but fails fast if you provide a null, so you know exactly what's wrong when you get a NullPointerException with the following:
the nameMapping array can't be null as it's used to map from fields to
columns
It also includes many bug fixes and new features (including Maven support and a new Dozer extension for mapping nested properties and arrays/Collections).
I don't see where you create ArrayList<FreebasePeopleResults> people, but you might verify that it has more than one element. As an example of coding to the interface, consider using List<FreebasePeopleResults> people as the formal parameter.
Addendum: Have you been able to make this Code example: Write a file with a header work?
Example: Here's a simplified example. I think you just need to specify the nameMapping when you invoke write(). Those names determine what get methods to call via introspection.
Console output:
name,age
Alpha,1
Beta,2
Gamma,3
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import org.supercsv.io.CsvBeanWriter;
import org.supercsv.io.ICsvBeanWriter;
import org.supercsv.prefs.CsvPreference;
public class Main {
private static final List<Person> people = new ArrayList<Person>();
public static void main(String[] args) throws IOException {
people.add(new Person("Alpha", 1));
people.add(new Person("Beta", 2));
people.add(new Person("Gamma", 3));
ICsvBeanWriter writer = new CsvBeanWriter(
new PrintWriter(System.out), CsvPreference.STANDARD_PREFERENCE);
try {
final String[] nameMapping = new String[]{"name", "age"};
writer.writeHeader(nameMapping);
for (Person p : people) {
writer.write(p, nameMapping);
}
} finally {
writer.close();
}
}
}
public class Person {
String name;
Integer age;
public Person(String name, Integer age) {
this.name = name;
this.age = age;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
CellProcessor[] processors = new CellProcessor[] { new Optional(), new NotNull(),
new Optional(), new Optional(), new NotNull(), new Optional()};
CsvBeanWriter writer = new CsvBeanWriter(file, CsvPreference.EXCEL_PREFERENCE)
writer.write(data,properties,processors);

Categories