I have two class Parent Class and Child classes as below:
#MappedSuperclass
public class ParentEntity implements DataSerializable {
private String createdBy;
private Date createdAt;
public String getCreatedBy() {
return createdBy;
}
public void setCreatedBy(String createdBy) {
this.createdBy = createdBy;
}
public Long getCreatedAt() {
return createdAt.getTime();
}
public void setCreatedAt(Date createdAt) {
this.createdAt = createdAt;
}
#Override
public void writeData(ObjectDataOutput out) throws IOException {
out.writeUTF(createdBy);
out.writeLong(this.getCreatedAt());
}
#Override
public void readData(ObjectDataInput in) throws IOException {
createdBy = in.readUTF();
createdAt = new Date(in.readLong());
}
}
Child class is as below:-
public class Child_Entity extends ParentEntity implements DataSerializable {
private String id;
private String name;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Override
public void writeData(ObjectDataOutput out) throws IOException {
out.writeUTF(id);
out.writeUTF(name);
}
#Override
public void readData(ObjectDataInput in) throws IOException {
id = in.readUTF();
name = in.readUTF();
}
}
I fetch these value from database and put into hazelcast cache iMap.
While getting values from cache I am getting id and name value correct, but createdAt and createdBy (Parent Class attributes ) values are null.
How can it is possible to serialize parent class also with child class.
You need to call super-class serialization methods in the child class methods. For instance;
public class Child_Entity extends ParentEntity implements DataSerializable {
private String id;
private String name;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id; }
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Override
public void writeData(ObjectDataOutput out) throws IOException {
super.writeData(out);
out.writeUTF(id);
out.writeUTF(name);
}
#Override
public void readData(ObjectDataInput in) throws IOException {
super.readData(in);
id = in.readUTF();
name = in.readUTF();
}}
Related
I am using JSON-B for output object to json and there is a circular reference in the object (please do not ask me to remove the circular reference), sample code as follows
The Person class contains a list of Property
and the Property class reference back the person which form a circular reference.
In the first print the json can be output, however in the second print statement, stack overflow error due to touch the circular reference of the object, I do not want to use #JsonbTransient to ignore any of them, how can I solve this?
I am expecting the json output as
{"id":1,"name":"Jhon","propertyList":[{"person":1, "propertyName":"Palace"},{"person":1, "propertyName":"Apartment"}]}
Sample Code:
import java.util.ArrayList;
import java.util.List;
import javax.json.bind.Jsonb;
import javax.json.bind.JsonbBuilder;
public class JsonTest {
public static void main(String[] args) throws InterruptedException {
Person person = new Person(1, "Jhon");
Jsonb jsonb = JsonbBuilder.create();
//no error as no property is added
System.out.println("jsonPerson without property: " + jsonb.toJson(person));
Property p1 = new Property();
p1.setPropertyName("Palace");
p1.setPerson(person);
Property p2 = new Property();
p2.setPropertyName("Apartment");
p2.setPerson(person);
person.getPropertyList().add(p1);
person.getPropertyList().add(p2);
/**
* stackoverflow here
*/
System.out.println("jsonPerson with property: " + jsonb.toJson(person));
}
public static class Property {
private Person person;
private String propertyName;
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
public String getPropertyName() {
return propertyName;
}
public void setPropertyName(String propertyName) {
this.propertyName = propertyName;
}
}
public static class Person {
private int id;
public Person() {
super();
}
public Person(int id, String name) {
super();
this.id = id;
this.name = name;
}
private String name;
private List<Property> propertyList = new ArrayList<>();
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 List<Property> getPropertyList() {
return propertyList;
}
public void setPropertyList(List<Property> propertyList) {
this.propertyList = propertyList;
}
}
}
Finally I give up using JSON-B and instead use Jackson, use the annotation #JsonIdentityInfo here is my solution for information:
import java.util.ArrayList;
import java.util.List;
import javax.json.bind.Jsonb;
import javax.json.bind.JsonbBuilder;
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JsonTest {
private static Person person = null;
private static List<Property> propertyList = new ArrayList<>();
public static void main(String[] args) throws Exception {
person = new Person(1, "Jhon");
propertyList.add(new Property(1, person, "Palace"));
propertyList.add(new Property(2, person, "Apartment"));
person.setPropertyList(propertyList);
jacksonTest();
//jsonbTest();
}
private static void jacksonTest()
throws Exception
{
String result = new ObjectMapper().writeValueAsString(person);
System.out.println("result: " + result);
}
private static void jsonbTest()
throws Exception
{
Jsonb jsonb = JsonbBuilder.create();
/**
* stackoverflow here
*/
System.out.println("jsonPerson with property: " + jsonb.toJson(person));
}
public static class Property extends BaseEntity {
private Person person;
private String propertyName;
public Property(int id, Person person, String propertyName) {
super();
setId(id);
this.person = person;
this.propertyName = propertyName;
}
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
public String getPropertyName() {
return propertyName;
}
public void setPropertyName(String propertyName) {
this.propertyName = propertyName;
}
}
public static class Person extends BaseEntity {
public Person() {
super();
}
public Person(int id, String name) {
super();
setId(id);
this.name = name;
}
private String name;
private List<Property> propertyList = new ArrayList<>();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Property> getPropertyList() {
return propertyList;
}
public void setPropertyList(List<Property> propertyList) {
this.propertyList = propertyList;
}
}
#JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public static abstract class BaseEntity {
private int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
}
Jackson output:
result: {"id":1,"name":"Jhon","propertyList":[{"id":1,"person":1,"propertyName":"Palace"},{"id":2,"person":1,"propertyName":"Apartment"}]}
I was wondering how to use jdbctemplate and RowMapper to create object with a list of objects?
Below are the three objects that I need to get mapped based on data from the db.
public class UserDTO {
private String userID;
private String email;
private List<RooftopDTO> rooftops;
public String getUserID() {
return userID;
}
public void setUserID(String userID) {
this.userID = userID;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public List<RooftopDTO> getRooftops() {
return rooftops;
}
public void setRooftops(List<RooftopDTO> rooftops) {
this.rooftops = rooftops;
}
}
public class RooftopDTO {
private String dealerID;
private String name;
private String address;
private List<VenueDTO> venues;
public String getDealerID() {
return dealerID;
}
public void setDealerID(String dealerID) {
this.dealerID = dealerID;
}
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 List<VenueDTO> getVenues() {
return venues;
}
public void setVenues(List<VenueDTO> venues) {
this.venues = venues;
}
}
public class VenueDTO {
private int integrationID;
private String rooftopID;
public int getIntegrationID() {
return integrationID;
}
public void setIntegrationID(int integrationID) {
this.integrationID = integrationID;
}
public String getRooftopID() {
return rooftopID;
}
public void setRooftopID(String rooftopID) {
this.rooftopID = rooftopID;
}
}
As you can see, I need to create lists of objects within each object. This is what I have so far in my MapperClass, but I can't figure out what else to do..
public class UserDTOMapper implements RowMapper<UserDTO> {
#Override
public UserDTO mapRow(ResultSet rs, int rowNum) throws SQLException {
UserDTO userDTO = new UserDTO();
RooftopDTO rooftops = new RooftopDTO();
VenueDTO venues = new VenueDTO();
ArrayList<VenueDTO> venueList = new ArrayList<>();
ArrayList<RooftopDTO> rooftopList = new ArrayList<>();
userDTO.setUserID(rs.getString("user_id"));
userDTO.setEmail(rs.getString("email"));
rooftops.setDealerID(rs.getString("dealer_id"));
rooftops.setAddress(rs.getString("addr_1"));
rooftops.setName(rs.getString("dealer_nm"));
venues.setIntegrationID(rs.getInt("integration_id"));
venues.setRooftopID("act_org_id");
}
}
Can someone help me finish this mapRow method?
I am developing and spring application and for object mapping I am using ModelMapper library.
I am able to map basic class mapping but when I am trying to map 2 collection elements, source is set of enumeration with additional property like name and description and destination is pojo having id, name and description.
I have tried typemap and converters in mapping profile but I am getting exception of mapper.
And the source class is from other application(whose dependency have been added in pom.xml). I also don't want source type as an argument in setter of destination.
Ex.
SOURCE:
public class VType{
private int id;
private String name;
private String description;
}
public class VDTO{
private Set<VType> vTypes;
public Set<VType> getVTypes(){
return this.vTypes;
}
public void setVType() { //here I don't want to pass source type as an argument
//code stuff that I don't know what to do here
}
}
SOURCE ENUM:
public enum SourceVType{
V1(1, "Name1", "Desc1");
V2(2, "Name2", "Desc2");
private Integer id;
private String name;
private String description;
SourceVType(Integer id, String name, String description) {
this.id = id;
this.name = name;
this.description = description;
}
//getter-setter
}
Have you tried converter feature of modelmapper. You can use typemap converter to achieve this requirement.
#RunWith(JUnit4.class)
public class TempTest {
#Test
public void TestThis(){
final ModelMapper mapper = new ModelMapper();
mapper.addMappings(new PropertyMap<SrcClass, DestClass>() {
#Override
protected void configure() {
this.map().setId(this.source.getId());
this.map().setName(this.source.getName());
mapper.createTypeMap(TypeEnum.class, TypeClass.class).setConverter(
new Converter<TypeEnum, TypeClass>() {
#Override
public TypeClass convert(MappingContext<TypeEnum, TypeClass> mappingContext) {
if (mappingContext.getSource() == null) {
return null;
}
TypeEnum typeEnum = mappingContext.getSource();
TypeClass typeClass = new TypeClass();
typeClass.setId(typeEnum.getId());
typeClass.setName(typeEnum.getName());
return typeClass;
}
});
}
});
SrcClass srcObj = new SrcClass();
srcObj.setId(1);
srcObj.setName("name");
srcObj.setTypes(new HashSet<>(Arrays.asList(TypeEnum.TYPE1, TypeEnum.TYPE2)));
DestClass dstObj = mapper.map(srcObj, DestClass.class);
Assert.assertEquals(srcObj.getId(), dstObj.getId());
Assert.assertEquals(srcObj.getName(), dstObj.getName());
Assert.assertEquals(srcObj.getTypes().size(), dstObj.getTypes().size());
for(TypeClass c : dstObj.getTypes()) {
TypeEnum e = TypeEnum.getById(c.getId());
Assert.assertNotNull(e);
Assert.assertTrue(srcObj.getTypes().contains(e));
}
}
public static <Source, Result> Set<Result> convertAll(Set<Source> source, Function<Source, Result> projection)
{
Set<Result> results = new HashSet<>();
if(source == null) return results;
for (Source element : source)
{
results.add(projection.apply(element));
}
return results;
}
public static class SrcClass{
private Integer id;
private String name;
private Set<TypeEnum> types;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<TypeEnum> getTypes() {
return types;
}
public void setTypes(Set<TypeEnum> types) {
this.types = types;
}
}
public static class DestClass{
private Integer id;
private String name;
private Set<TypeClass> types;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<TypeClass> getTypes() {
return types;
}
public void setTypes(Set<TypeClass> types) {
this.types = types;
}
}
public static enum TypeEnum{
TYPE1(1, "Type 1")
, TYPE2(2, "Type 2")
, TYPE3(3, "Type 3")
, TYPE4(4, "Type 4");
private Integer id;
private String name;
TypeEnum(Integer id, String name) {
this.id = id;
this.name = name;
}
private static final Map<Integer, TypeEnum> byId = new HashMap<>();
private static final Map<String, TypeEnum> byName = new HashMap<>();
static {
for (TypeEnum e : TypeEnum.values()) {
if (byId.put(e.getId(), e) != null) {
throw new IllegalArgumentException("duplicate id: " + e.getId());
}
if (byName.put(e.getName(), e) != null) {
throw new IllegalArgumentException("duplicate name: " + e.getName());
}
}
}
public Integer getId() {
return this.id;
}
public String getName() { return this.name; }
public static TypeEnum getById(Integer id) {
return byId.get(id);
}
public static TypeEnum getByName(String name) {
return byName.get(name);
}
}
public static class TypeClass{
private Integer id;
private String name;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
}
I have following json data
{"id":10606,
"name":"ProgrammerTitle",
"objectMap":{"programme-title":"TestProgramme","working-title":"TestProgramme"}
}
I want to set this data to my pojo object
public class TestObject {
private Long id;
private String name;
#JsonProperty("programme-title")
private String programmeTitle;
#JsonProperty("working-title")
private String workingTitle;
}
Here i am able to set id and name in my test object but for object map i am not able to set data.
So i have made on more class for ObjectMap which contains programmeTitle & workingTitle this works fine but i can't set this fields directly to my pojo object
is this possible to set?
I am using Jackson Object Mapper to convert json data.
It is working fine if i create another java object inside my pojo like:
public class TestObject {
private Long id;
private String name;
#JsonProperty("objectMap")
private ObjectMap objectMap;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public ObjectMap getObjectMap() {
return objectMap;
}
public void setObjectMap(ObjectMap objectMap) {
this.objectMap = objectMap;
}
}
public class ObjectMap {
#JsonProperty("programme-title")
private String programmeTitle;
#JsonProperty("working-title")
private String workingTitle;
public String getProgrammeTitle() {
return programmeTitle;
}
public void setProgrammeTitle(String programmeTitle) {
this.programmeTitle = programmeTitle;
}
public String getWorkingTitle() {
return workingTitle;
}
public void setWorkingTitle(String workingTitle) {
this.workingTitle = workingTitle;
}
}
If your JSON is like this
{"id":10606,
"name":"ProgrammerTitle",
"objectMap":{"programme-title":"TestProgramme","working-title":"TestProgramme"}
}
then you may write your object mapper class like this..
public class Program{
public static class ObjectMap{
private String programme_title, working_title;
public String getprogramme_title() { return programme_title; }
public String getworking_title() { return working_title; }
public void setprogramme_title(String s) { programme_title= s; }
public void setworking_title(String s) { working_title= s; }
}
private ObjectMap objMap;
private String name;
public ObjectMap getobjectMap () { return objMap; }
public void setObjectMap (ObjectMap n) { objMap= n; }
private Long id;
public Long getId() {return id;}
public void setId(Long id) {this.id = id;}
private String name;
public String getName() {return name;}
public void setName(String name) {this.name = name;}
}
please refer this check it
You can write your own deserializer for this class:
class EntityJsonDeserializer extends JsonDeserializer<Entity> {
#Override
public Entity deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
Root root = jp.readValueAs(Root.class);
Entity entity = new Entity();
entity.setId(root.id);
entity.setName(root.name);
if (root.objectMap != null) {
entity.setProgrammeTitle(root.objectMap.programmeTitle);
entity.setWorkingTitle(root.objectMap.workingTitle);
}
return entity;
}
private static class Root {
public Long id;
public String name;
public Title objectMap;
}
private static class Title {
#JsonProperty("programme-title")
public String programmeTitle;
#JsonProperty("working-title")
public String workingTitle;
}
}
Your entity:
#JsonDeserialize(using = EntityJsonDeserializer.class)
class Entity {
private Long id;
private String name;
private String programmeTitle;
private String workingTitle;
//getters, setters, toString
}
And usage example:
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
public class JacksonProgram {
public static void main(String[] args) throws IOException {
ObjectMapper mapper = new ObjectMapper();
Entity entity = mapper.readValue(jsonString, Entity.class);
System.out.println(entity);
}
}
Above program prints:
Entity [id=10606, name=ProgrammerTitle, programmeTitle=TestProgramme, workingTitle=TestProgramme]
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);
}
}