I have the below json, which i need to read and construct as Map<NamePlateOrder, List<Orders>>
Sample json:
`{
"orders":[
{
"order":[
{
"OrderReference":{
"reference":68203486,
"version":1
}
},
{
"OrderReference":{
"reference":68203487,
"version":1
}
}
],
"nameplate":{
"id":"98ZZ",
"label":"VEC"
}
}
]
}`
Below is the code:
public class NamePlateOrder {
public ArrayList<Orders> orders;
#EqualsAndHashCode
#AllArgsConstructor
#NoArgsConstructor
#Getter
#Setter
#Builder
public static class NameplateCatalogForOrder {
public String id;
public String label;
}
#EqualsAndHashCode
#AllArgsConstructor
#NoArgsConstructor
#Getter
#Setter
#Builder
public static class Orders {
public List<Order> order; //this should be stored as value.
public NameplateCatalogForOrder nameplate; //this should be stored as key
}
#EqualsAndHashCode
#AllArgsConstructor
#NoArgsConstructor
#Getter
#Setter
#Builder
public static class Order {
#JsonProperty("OrderReference")
public OrderReference orderReference;
}
#EqualsAndHashCode
#AllArgsConstructor
#NoArgsConstructor
#Getter
#Setter
#Builder
public static class OrderReference {
public int reference;
public int version;
}
}
Sample code tried to construct Map<NameplateCatalogForOrder, List<Orders>>
`NamePlateOrder models = om.readValue(sql2, NamePlateOrder.class);
System.out.println("NNamePlateWithOrder " + models);
Map<NamePlateOrder.NameplateCatalogForOrder, List<NamePlateOrder.Order>> nameplateListMap = new HashMap<>();
for(NamePlateOrder.Orders firstOrders : models.getOrders()){
NamePlateOrder.NameplateCatalogForOrder n1 = firstOrders.getNameplate();
List<NamePlateOrder.Order> ordersListForNamePlate = firstOrders.getOrder();
nameplateListMap.put(n1, ordersListForNamePlate);
}`
But the output when executed the above code is not as expected. The key n1 is printing as object reference. The expected output should be same as the sample json which we are reading to construct the same.
Any inputs would be helpful.
#EqualsAndHashCode
#AllArgsConstructor
#NoArgsConstructor
#Getter
#Setter
#Builder
public static class Order {
This christmas tree does not include #ToString, hence, the toString() implementation of these things would print something like Order#12af9cc, which I think is what you mean with 'prints its object reference'. In other words, your code is doing exactly what you asked it to.
I suggest you use #Value #Builder instead and ditch the setters. It's a bit odd to want a builder for a mutable class, after all (why not just invoke the setters instead?). If you must have them, #NoArgsConstructor #AllArgsConstructor #Value #Data works too. #Data combines #EqualsAndHashCode #Getter #Setter #ToString which is what you want.
Related
I want to communicate with another application via REST that uses JSON with multi-layer wrapping.
e.g.:
I have the following POJO class:
#XmlRootElement
#AllArgsConstructor
#NoArgsConstructor
public class Message {
#Getter
#Setter
#XmlElement(name="meta")
private WrapperMeta metaParameters;
#Getter
#Setter
#XmlElement(name="message")
private WrapperMessage messageParameters;
}
the Wrapper class:
#Getter
#Setter
#XmlElement(name="parameters")
private MetaParameters meta;
}
the JSON generated from it:
{
"meta": {
"parameters": {
"service": "some",
"sender": {
"id": "2",
"name": "Jane Doe"
}
}
},
"message": {
"parameters": {
"message": "hi"
"sent": 1630597537
}
}
}
I want to get rid of the Wrapper classes, and instead have a more elegant solution.
e.g., with Annotations, like this:
#XmlRootElement
#AllArgsConstructor
#NoArgsConstructor
public class Message {
#Getter
#Setter
#XmlElementWrapper(name="meta")
#XmlElement(name="parameters")
private MetaParameters metaParameters;
#Getter
#Setter
#XmlElementWrapper(name="message")
#XmlElement(name="parameters")
private MessageParameters message;
}
But the XmlElementWrapper annotation only seems to add the wrapping for XML, not JSON.
Replace your #XmlElement with #JsonProperty. Like this,
#Getter
#Setter
#AllArgsConstructor
#NoArgsConstructor
public class Message {
#JsonProperty("meta")
private WrapperMeta metaParameters;
#JsonProperty("message")
private WrapperMessage messageParameters;
}
Change your WrapperMessage class like this.
#Getter
#Setter
public class WrapperMessage {
#JsonUnwrapped
private MetaParameters meta;
}
Note: You can add Getter and #Setter in class level. Like above examples
Assuming two simple classes:
#Data
#Builder
#NoArgsConstructor
#AllArgsConstructor
#EqualsAndHashCode
public class Party {
protected Long id;
protected String status;
}
#Data
#SuperBuilder
#NoArgsConstructor
#AllArgsConstructor
#EqualsAndHashCode(callSuper = true)
public class Person extends Party {
private String name;
private Long sex;
}
The compilation fails on the following error. Upon reading Lombok | #SuperBuilder I have no idea what I could miss.
C:\Dev\companyproject\src\main\java\com\companyproject\entity\Person.java:12
java: type com.companyproject.entity.Party.PartyBuilder does not take parameters
The issue here is the incorrect #Builder annotation on the parent class. The documentation for #SuperBuilder mentions:
Most importantly, it requires that all superclasses also have the #SuperBuilder annotation.
So the correct parent class would be:
#Data
#SuperBuilder // <- annotation replaced here
#NoArgsConstructor
#AllArgsConstructor
#EqualsAndHashCode
public class Party {
protected Long id;
protected String status;
}
Addendum:
A key difference between both annotations is that #SuperBuilder also creates a constructor of the class expecting a corresponding builder argument.
For Party it would look like:
protected Party(PartyBuilder<?, ?> b) {
this.id = b.id;
this.status = b.status;
}
and for Person:
protected Person(PersonBuilder<?, ?> b) {
super(b);
this.name = b.name;
this.sex = b.sex;
}
As you can see, the child class constructor wants to pass its own builder to the parent class constructor and this will only be possible if there is a matching constructor there, and #Builder wouldn't generate it.
Also PersonBuilder<> extends PartyBuilder<>, that is why calling super with the child type builder works fine here.
I have two lists first List<ClassOne> and second List<ClassTwo>.
ClassOne has the following fields:
ClassOne:
#AllArgsConstructor
#NoArgsConstructor
#Getter
#Setter
#Builder
public class ClassOne {
private Integer idToInsert;
private String fieldToCompare;
private List<AnotherClass> anotherClass;
}
And ClassTwo has the following fields:
#AllArgsConstructor
#NoArgsConstructor
#Getter
#Setter
#Builder
public class ClassTwo {
private Integer idToInsert;
private String fieldToCompare;
}
And I have this two Lists List<ClassOne> and List<ClassTwo>.
ClassTwo contains the idToInsert field, which must be inserted in ClassOne, when the fieldToCompare field is the same in both classes.
Something like
if(classtwo.getFieldToCompare.equals(classOne.getFieldTocompare){
classOne.setIdToInsert(classTwo.getIdToInsert());
}
How can I do this comparing this two lists?
I will suggest to collect List<ClassTwo> into Map<String,Integer> which is Map(fieldToCompare, idToInsert) for better performance
Map<String,Integer> classTwoMap = classTwoList.stream()
.collect(Collectors.toMap(two->two.getFieldToCompare(), two->two.getIdToInsert()));
And then now just use forEach on classListOne
classListOne.forEach(one -> one.setidToInsert(classTwoMap.getOrDefault(one.getFieldTocompare(),one.getIdToInsert())));
In inheritance, I'm not getting the Child class properties. Code is shown below
#Setter
#Getter
#AllArgsConstructor
#SuperBuilder
#EqualsAndHashCode
Class Employee {
private String fName;
private String lName;
private Account account;
}
#Setter
#Getter
#AllArgsConstructor
#SuperBuilder
#EqualsAndHashCode
Class Account {
private accountNo;
}
#Setter
#Getter
#AllArgsConstructor
#SuperBuilder
#EqualsAndHashCode
Class SavingAccount extends Account{
private balance
}
#Setter
#Getter
#AllArgsConstructor
#SuperBuilder
#EqualsAndHashCode
class CurrentAccount extends Account{
private balance;
}
At runtime can get any type of account and will set it into Employee and its correctly happening but the same object goes to Kafka topic and another consumer consumes it there I am getting Employee & Account properties not subclass of account. May be something is wrong with Lombok annotations. Please help
I have a SpringBoot 2 app that uses using Couchbase as a database, Spring-Boot and Spring-Data and Lombok fot the getters and equals method
I have created this Repository
#ViewIndexed(designDoc = "bendicionesDoc")
public interface BenRepository extends CouchbaseRepository<BendicionesDoc, String> {
#Query("#{#n1ql.selectEntity} where #{#n1ql.filter} AND ANY uuid IN data.identifier.id SATISFIES uuid = $1 END")
List<BendicionesDoc<Item>> findById(String id);
}
and here all the objects created with Lombok library
public class BendicionesDoc<T>implements Serializable {
#Field
private T data;
}
and
#Data
#Builder
#NoArgsConstructor
#AllArgsConstructor
#JsonInclude(NON_NULL)
public class Item {
private List<Identifier> identifier;
}
and
#Data
#Builder
#NoArgsConstructor
#AllArgsConstructor
#JsonInclude(NON_NULL)
#EqualsAndHashCode
public class Identifier {
private String id;
private MasterServant idContext;
private MasterServant idScope;
}
and
#Data
#Builder
#NoArgsConstructor
#AllArgsConstructor
#JsonInclude(NON_NULL)
#EqualsAndHashCode(onlyExplicitlyIncluded = true)
public class MasterServant {
private String context;
#JsonValue
#EqualsAndHashCode.Include
private String value;
private Name valueDescription;
#JsonCreator
public MasterServant(String value) {
this.value = value;
}
}
But when I run the repository query I got always 0 results, even there are docs. in the DB:
You need to define your reference type in CouchbaseRepository<T, K> then simply add the reference type Item as CouchbaseRepository<BendicionesDoc<Item>, String> and just use Repository query keywords for findById(String id).
public interface BenRepository extends CouchbaseRepository<BendicionesDoc<Item>, String> {
List<BendicionesDoc<Item>> findById(String id);
}