I have two related Entities in my application integratorDetails, IntegratorChannelDetails. What I want to achieve is to map integratorDetails and IntegratorChannelDetails to a DTO Object IntegratorAllInfoDto which has similar fields as the entities, using ModelMapper, but I am not sure how to do that, below are the entities
integratorDetails
import com.couchbase.client.java.repository.annotation.Field;
import com.couchbase.client.java.repository.annotation.Id;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.couchbase.core.mapping.Document;
import java.util.Date;
import java.util.List;
#Document
#Data
#Builder
#NoArgsConstructor
#AllArgsConstructor
public class IntegratorDetails {
#Id
private String integratorId;
#Field
private String name;
#Field
private String accountId;
#Field
private String status;
private String privateKey;
private String publicKey;
private List<ThirdPartyKey> thirdPartyKey;
private Date createdTime;
}
IntegratorChannelDetails
import com.couchbase.client.java.repository.annotation.Id;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.couchbase.core.mapping.Document;
import java.util.List;
#Document
#Data
#Builder
#NoArgsConstructor
#AllArgsConstructor
public class IntegratorChannelDetails {
#Id
private String integratorChannelid;
private String accountId;
private String type;
private List<ChannelType> channelTypes;
private List<ChannelList> channelList;
private List<String> fixedChannels;
private String timeServiceUrl;
private List<RibbonRules> ribbonRules;
int numberOfSlots=4;
}
And my Dto is
import com.tdchannels.admin.ms.channel.db.entity.ChannelList;
import com.tdchannels.admin.ms.channel.db.entity.RibbonRules;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;
import java.util.List;
#Data
#Builder
#NoArgsConstructor
#AllArgsConstructor
public class IntegratorAllInfoDto<T> {
private String integratorId;
private String name;
private String accountId;
private String status;
private Date createdTime;
private List<ChannelTypeDto> channelTypes;
private List<ChannelList> channelList;
private List<String> fixedSlots;
private String publicKey;
private List<ThirdPartyKeyDto> thirdPartyKey;
private List<RibbonRules> ribbonRules;
}
If you need to map multible objects into a single destination you do like this.
ModelMapper modelMapper = new ModelMapper();
IntegratorDTO dto= modelMapper.map(details, IntegratorDTO.class);
//This will add additional values to the dto.
modelMapper.map(integratorChannelDetails, dto);
Like the documentation http://modelmapper.org/getting-started/
You can concat the names of entities on DTO, like:
Source model
// Assume getters and setters on each class
class Order {
Customer customer;
Address billingAddress;
}
class Customer {
Name name;
}
class Name {
String firstName;
String lastName;
}
class Address {
String street;
String city;
}
Destination Model
// Assume getters and setters
class OrderDTO {
String customerFirstName;
String customerLastName;
String billingStreet;
String billingCity;
}
Related
I am defining a class User which is a parent to my two other classes: Submitter and Assignee. User has all my attributes listed and Submitter and Assignee will just inherit all its attributes. A submitter can submit many Requests.
The models I have coded look like this:
User
package com.merck.trackertest.models;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.Table;
import lombok.Data;
import lombok.NoArgsConstructor;
#Entity
#Data
#NoArgsConstructor
#Table(name = "users")
#Inheritance(strategy = InheritanceType.JOINED)
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String firstName;
private String lastName;
private String isid;
private String email;
public User(String firstName, String lastName, String isid, String email) {
this.firstName = firstName;
this.lastName = lastName;
this.isid = isid;
this.email = email;
}
}
Submitter
package com.merck.trackertest.models;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
#Entity
#Data
#NoArgsConstructor
#EqualsAndHashCode(callSuper = true)
public class Submitter extends User {
#OneToMany(
cascade = CascadeType.ALL,
orphanRemoval = true
)
#JoinColumn(
name = "submitter_id",
referencedColumnName = "id"
)
private List<Request> requests = new ArrayList<>();
public Submitter(String firstName, String lastName, String isid, String email) {
super(firstName, lastName, isid, email);
}
public void addToList(Request request) {
requests.add(request);
}
public void deleteFromList(Request request) {
requests.remove(request);
}
}
Request
package com.merck.trackertest.models;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import lombok.Data;
import lombok.NoArgsConstructor;
#Entity
#Data
#NoArgsConstructor
#Table(name = "requests")
public class Request {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String receivedDate;
private String startDate;
private String endDate;
private String requestNumber;
#ManyToOne
#JoinColumn(name = "submitter_id", referencedColumnName = "id")
private Submitter submitter;
private String assigneeId;
private String status;
public Request(String receivedDate, String startDate, String requestNumber, String status) {
this.receivedDate = receivedDate;
this.startDate = startDate;
this.requestNumber = requestNumber;
this.status = status;
}
}
I have not modelled the Assignee table as of yet.
My concern is the table Submitter does not show anything but the id, is there a way to present the data with the id to the list of requests. Would using #Embeddable and #Embedded make the most sense here, can I do that even though I have defined Request as an Entity. What is the correct way of referencing a OneToMany Bidirectional relationship which uses Inheritance.
Table looks like the below which doesn't provide any useful information.
If you want the Submitter and Assignee tables created with all the cloumns from the user class, you have 2 choices
Mapped super class :
You need make the user class mapped super class by adding the #MappedSuperClass annotation and removing the #Entity and #Table annotations.
Classes having the #MappedSuperClass annotation won't be persisted in the database (no table created).
Entities extending this MappedSuperClass will inherit its properties.
In the database, this will correspond to one Sumbitter table with columns for the declared and inherited fields of the User class.
Table per class strategy :
The Table per Class strategy maps each entity to its table, which contains all the properties of the entity, including the ones inherited.
For this you need to modify the inheritance strategy annotation :
#Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
I basically have a Class A and a Class B where ClassA has many of ClassB, i use a OneToMany annotation to get a List of all the ClassB Objects that belong to a ClassA Object, now i want to convert the information in ClassA to a ClassA DTO but in the DTO i only want a list of the ids of the ClassB Objects and not the Objects.
Im using the Spring Framework and the ModelMapper, the data of the objects can be accessed via rest api in Json format.
ClassA:
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.*;
import java.io.Serializable;
import java.time.LocalDate;
import java.util.ArrayList;
#Getter
#Setter
#NoArgsConstructor
#AllArgsConstructor
#Entity
#Table(name = "ClassA")
public class ClassA implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#OneToMany(
mappedBy = "myClassA",
cascade = CascadeType.ALL,
orphanRemoval = true
)
private java.util.List<Domain> domains = new ArrayList<>();
}
ClassB:
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import javax.persistence.*;
import java.io.Serializable;
import java.time.LocalDate;
#Getter
#Setter
#NoArgsConstructor
#AllArgsConstructor
#Entity
#Table(name = "ClassB")
public class ClassB implements Serializable {
private static final long serialVersionUID = 1L;
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Id
private Long id;
#Column(name="projekt_id")
private Long projectId;
#ManyToOne
#JsonIgnore
#JoinColumn(name = "projekt_id", insertable = false, updatable = false)
private ClassA myClassA;
}
Given below is the example XML file. I want to pull all the information in the XML into a Java object using JAXB. Please note the tag is repeated.
<ICExt>
<AA>
<PA1>20067</PA1>
<PA2>
<FFGAG>
<KICUC>
<R_CAT_NAME>testing1234</R_CAT_NAME>
<params>
<req_id>7746318</req_id>
<FNAME>Testing line</FNAME>
<ldata_group_id/>
<edate>2010-01-01</edate>
<sdate/>
<rep_cat_id>265131</rep_cat_id>
<ac_param_group_id/>
</params>
<Employees>
<empl_rec>
<emp_id>1000</emp_id>
<Salary>20000</Salary>
</empl_rec>
</Employees>
<Employees>
<empl_rec>
<emp_id>5600</emp_id>
<Salary>34000</Salary>
</empl_rec>
</Employees>
</KICUC>
</FFGAG>
</PA2>
</AA>
</ICExt>
Any ideas?
I have managed to parse the XML into Java object by using JAXB.
ICExt is a common class.
ICExtUnmarshaler is a parser
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
#XmlRootElement(name = "ICExt")
#XmlAccessorType(XmlAccessType.FIELD)
#EqualsAndHashCode
#Setter
#Getter
#ToString
public class ICExt {
#XmlElement(name = "AA")
private AA aa;
#Setter
#Getter
#XmlAccessorType(XmlAccessType.FIELD)
#EqualsAndHashCode
public static class AA {
#XmlElement(name = "PA1")
private String pa1;
#XmlElement(name = "PA2")
private PA2 pa2;
}
#Setter
#Getter
#XmlAccessorType(XmlAccessType.FIELD)
#EqualsAndHashCode
public static class PA2 {
#XmlElement(name = "FFGAG")
private FFGAG ffgag;
}
#Setter
#Getter
#XmlAccessorType(XmlAccessType.FIELD)
#EqualsAndHashCode
public static class FFGAG {
#XmlElement(name = "KICUC")
private KICUC kicuc;
}
#Setter
#Getter
#XmlAccessorType(XmlAccessType.FIELD)
#EqualsAndHashCode
public static class KICUC {
#XmlElement(name = "R_CAT_NAME")
private String rCatName;
#XmlElement(name = "Employees")
private List<Employee> employees = new LinkedList<>();
#XmlElement(name = "params")
private Params params;
}
#Setter
#Getter
#XmlAccessorType(XmlAccessType.FIELD)
#EqualsAndHashCode
public static class Params {
#XmlElement(name = "req_id")
private String reqId;
#XmlElement(name = "sdate")
private Date startDate;
#XmlElement(name = "rep_cat_id")
private String repCatId;
#XmlElement(name = "ldata_group_id")
private String lDataGroupId;
#XmlElement(name = "ac_param_group_id")
private String acParamGroupId;
#XmlElement(name = "edate")
private Date endDate;
#XmlElement(name = "FNAME")
private String fName;
}
#Setter
#Getter
#XmlAccessorType(XmlAccessType.FIELD)
#EqualsAndHashCode
public static class Employee {
#XmlElement(name = "empl_rec")
private EmplRec emplRec;
}
#Setter
#Getter
#XmlAccessorType(XmlAccessType.FIELD)
#EqualsAndHashCode
public static class EmplRec {
#XmlElement(name = "Salary")
private String salary;
#XmlElement(name = "emp_id")
private String empId;
}
}
import javax.xml.bind.JAXBContext;
import java.io.StringReader;
public class ICExtUnmarshaler {
public ICExt unmarshal(String xmlContent) throws Exception {
JAXBContext context = JAXBContext.newInstance(ICExt.class);
return (ICExt) context.createUnmarshaller().unmarshal((new StringReader(xmlContent)));
}
}
and so far i have made bean class like that
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
#NoArgsConstructor
#Getter
#Setter
#Entity
#Table(name="logintableetech")
public class Student {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="student_id")
private int id;
#Column(name="full_name")
private String name;
#Column(name="bebo_reg_id")
private String regId;
#Column(name="password")
private String password;
#Column(name="email")
private String email;
}
Please help me to choose which class should i use for appropariate date ,i want birthdate as date entered by user and date_registed for date as current timestamp and also tell me how to save for enum in databse for mysql what data type should i use String (if possible) or Enum.
I've been trying to use Jackson annotations to avoid cyclic association but it doesn't seem to work as expected and I still get a stackoverflow
Allergens class:
import com.fasterxml.jackson.annotation.JsonManagedReference;
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
import java.io.Serializable;
import javax.persistence.*;
/**
* The persistent class for the allergens database table.
*
*/
#Entity
#Table(name="allergens")
#NamedQuery(name="Allergen.findAll", query="SELECT a FROM Allergen a")
//#JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class, property="#id")
public class Allergen{
private static final long serialVersionUID = 1L;
#Id
private int id;
private boolean isEnabled;
private String title;
//bi-directional many-to-one association to Recipe
#ManyToOne
#JsonManagedReference
private Recipe recipe;
//+getters/setters
Recipe Class
import com.fasterxml.jackson.annotation.JsonBackReference;
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
import java.io.Serializable;
import javax.persistence.*;
import java.util.List;
/**
* The persistent class for the recipes database table.
*
*/
#Entity
#Table(name="recipes")
#NamedQuery(name="Recipe.findAll", query="SELECT r FROM Recipe r")
//#JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class, property="#id")
public class Recipe{
private static final long serialVersionUID = 1L;
#Id
private int id;
private String complexity;
private int cookingTime;
private String description;
private int estimatedTime;
private String imageUrl;
private String information;
private boolean isPromoted;
private int preparationTime;
private float servings;
private String title;
private String type;
//bi-directional many-to-one association to Allergen
#OneToMany(mappedBy="recipe")
#JsonBackReference
private List<Allergen> allergens;
//+getters/setters
I've also tried annotating both classes with #JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class, property="#id") but that also didn't work unfortunately
Is there anything I'm missing?
Also, my pom.xml contains
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.8.8</version>
</dependency>
Do I need anything else for jackson?
You can try to add #JsonIgnore on the property that is causing the circular reference. This will tell Jackson not to serialize that property.