Is there a class level annotation for jackson's #JsonProperty ? Without knowing what field names are in the class, I can be able to annotate the class with a annotation and it will map it for me automatically?
Currently I have to annotate each field with a JsonProperty, is there something I can do at the class level that servers the same purpose?
public class myEntity() {
#JsonProperty("banner")
private String banner;
#JsonProperty("menu")
private String menu;
}
Class level annotation
#JsonRootName("Response")
public class SuperResponse {
...
}
Result:
<Response>
...
</Response>
#JsonProperty is not class level annotation, and you don't need to mark your class with any annotation. If you provide your class name as an argument to parser it will know how to map it according to your getter methods. It is as if every getter method has been marked with #JsonProperty without any argument
#JsonRootName(value = "user")
public class User {
public int id;
public String name;
}
Related
I can declare JAXB element in two ways:
#XmlElement
public int x;
or
private int x;
#XmlElement
public int getX(){...}
The first variant, AFAIK, creates getter, mapped to XML, anyway. What is the difference between these two ways?
It relates to the #XmlAccessorType annotation.
XmlAccessType.PROPERTY : Fields are bound to XML only when they are explicitly annotated by some of the JAXB annotations.
XmlAccessType.FIELD: Getter/setter pairs are bound to XML only when they are explicitly annotated by some of the JAXB annotations
Update to explain based on comment:
Let's consider a simple xml that looks like this:
<root>
<value>someValue</value>
</root>
And we have a class:
#XmlRootElement(name = "root")
//#XmlAccessorType(XmlAccessType.PROPERTY)
#XmlAccessorType(XmlAccessType.FIELD)
public class DemoRoot {
#XmlElement
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
If you try to unmarshal using XmlAccessType.FIELD and the #XmlElement annotation above the field, then you will unmarshal fine.
If you use XmlAccessType.PROPERTY you will receive the following error:
IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions Class has two properties of the same name "value"
This is because it takes into consideration both the explicitly annotated with #XmlElement field 'value' and the getters/setters.
And vice versa if you move the #XmlElement annotation on the getter/setter.
The use of #XMLElement (and similar annotations) before fields or before getters is well explained in this post: http://blog.bdoughan.com/2011/06/using-jaxbs-xmlaccessortype-to.html.
The following annotation before a class determines the XML bindings of fields/getters:
#XmlAccessorType(XmlAccessType.PUBLIC_MEMBER): public fields, annotated fields and properties
#XmlAccessorType(XmlAccessType.PROPERTY): annotated fields and properties
#XmlAccessorType(XmlAccessType.FIELD): fields and annotated properties
#XmlAccessorType(XmlAccessType.NONE): annotated fields and annotated properties
I have a JPA transient property in an entity which has a calculated value based on multiple fields in the POJO. All these calculations are done in the GETTER of that property.
But, Jackson doesnt seem to be using the GETTER when creating the JSON for that POJO.
How do I configure Jackson to use getter for the property?
My POJO looks something like below
#Entity
public class ProductSummaryEntity implements Serializable {
#Basic
private String field1;
// GETTER and SETTER for Field1
#Basic
private String field2;
// GETTER and SETTER for Field2
#Transient
private String field3;
public String getField3(){
setField3(field1 + field2);
return this.field3;
}
public void setField3(String temp){
this.field3=temp;
}
}
This link to a blog by #sghill has been posted on SO before and shows you how to customize the serialization process: https://www.sghill.net/how-do-i-write-a-jackson-json-serializer-deserializer.html
Essentially, annotate your POJO with #JsonSerialize(using = CustomSerializer.class) and then implement a class CustomSerializer that's extending from JsonSerializer. In your implementation you can build the JSON however you like and calculate values on the fly or call your getters.
No, I don't think you can serialize transient field unless there is something latest is there.
I have many entities with common properties. There is no xml schema, so I write jaxb entities on my own.
abstract class SuperEntity {
protected String id;
protected String name;
#XmlElement
public void setId() { .. sets Id .. }
#XmlElement
public void setName() { .. sets name .. }
}
// id and name are null after deserialization .. they are completely ignored
// there are other entities such as this, I don't want to repeat my code
#XmlRootElement
#XmlSeeAlso({SuperEntity.class})
class SpecificEntity extends SuperEntity {
protected String specificField;
#XmlElement
public void setSpecificField() { .. sets specific field .. }
}
SuperEntity is not deserialized (unmarshelled) at all, leaving fields null. If i copy fields and setters from superclass to specific class, it works, but I dont want to just copy that code to every child entity. Thank you for your help.
Change the class definitions to
#XmlRootElement
#XmlSeeAlso({SpecificEntity.class})
abstract class SuperEntity {
#XmlRootElement
class SpecificEntity extends SuperEntity {
When JAXB is processing a class model it will also process super classes (the ones not annotated with #XmlTransient). By default it won't process subclasses. The #XmlSeeAlso needs to go on the super class and reference the subclasses.
Suppose I have some POJO class that can be stored in my DB.
class SomeClass {
private String name;
private String surname;
private Address address;
//getters and setters
}
In this class, I have some inner class that defines some location.
class Address {
private String country;
private String city;
//getters and setters
}
My task - to collect some information from external sources using XML with different schemas e.g.:
schema1:
<someClass>
<first>John</first>
<last>Blue</last>
<location>Country, City, 123456</location>
</someClass>
schema2:
<someClass>
<credentials>John Blue</credentials>
<address>Country, City</p1>
<p>123456</p>
</someClass>
and so on.
For this task I'm using JAXB and inheritance for each schema, every object I define as #XmlElement with name and this works ok with simple strings and even with location with appropriate #XmlJavaTypeAdapter. But I have problems when parent class has the same element as inherited, but different type, e.g:
<someClass>
<credentials>John Blue</credentials>
<address>Country, City</p1>
<p>123456</p>
</someClass>
class InheritedClass extends SomeClass {
#Override
#XmlElement(name = "address")
public void setAddress(String address) {
//do some work to parse string to Address.class
//also i tried to use XmlJavaTypeAdapter for this method(with Address.class)
//also i tried to use XmlElementRef for Address.class
super.setAddress(addressClass);
}
}
When I'm trying to unmarshal such schema JAXB avoid my overridden method and uses parent with null Address object. I've tried such solutions:
#XmlElementRef
http://blog.bdoughan.com/2010/11/jaxb-and-inheritance-using-substitution.html
static inner #XmlJavaTypaAdapter http://blog.bdoughan.com/2012/01/jaxb-and-inhertiance-using-xmladapter.html
The main problem that I cannot modify external XML, only adapts it for my purposes. Also, i cannot modify POJO class because it store in DB and a have a lot of external XML's (so a lot of JAXB entities to unmarshal and adapt).
I have an Entity class
#Entity
#Table(name = "rule")
public class Rule implements Cloneable, Serializable, IPojoGenEntity, IRule, SequencedEntity {
private String name;
private Service service;
//getter .. setter for service and name
public String getServiceName() {
return (this.service.getName());
}
public void setServiceName(String servicename) {
this.service.setName(servicename);
}
}
I am getting exception for getting service name through RulClass object
public String getServiceName() {
return (this.service.getName());
}
Stack Trace
Caused by: com.ibm.db2.jcc.b.SqlException: "RULE0_.SERVICENAME" is not valid in the context where it is used.
at com.ibm.db2.jcc.b.fg.e(fg.java:1596)
at com.ibm.db2.jcc.b.fg.a(fg.java:1206)
at com.ibm.db2.jcc.a.gb.g(gb.java:140)
at com.ibm.db2.jcc.a.gb.a(gb.java:39)
at com.ibm.db2.jcc.a.w.a(w.java:34)
at com.ibm.db2.jcc.a.vb.g(vb.java:139)
Can we use such getter and setter in an entity class?
I am using hibernate, spring, DB2, IBM WebSphere
You should either make it #Transient as it was mentioned if you don't want to store it
OR
Define
#javax.persistence.Column(name = "service_id") field annotation for the getter to let hibernate know which column to use.
OR
Rename DB to have the service field "SERVICENAME" to use default column name
There is the Transient annotation to tell Hibernate to ignore a field. So:
#Transient
private Service service;
From very similar SO question: Make hibernate ignore class variables that are not mapped.
As serviceName was not a member of Rule class so there is a problem with method name. Name cannot be like
getServiceName
setServiceName
rather it should be something other than get or set prefix
fetchServiceName
addServiceName