Spring Java Inheritance not working with lombok - java

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

Related

Map<classObject,List> is not formed as expected

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.

Lombok #SuperBuilder doesn't take parameters

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.

Mapping DTO to specific subclass of parent entiy using Spring JPA where InheritanceType.TABLE_PER_CLASS

I am trying to map DTO to the corresponding #Entity in the service layer.
Condition may be of a set of types: Amount, Title, Date. Each condition, except Amount, has a unique predefined set of clauses.
TitleCondition: includes, startsWith
DateCondition: from, until
The idea is to use common Condition entity with #Inheritance(strategy= InheritanceType.TABLE_PER_CLASS).
The 2 problems I see with this code is:
It is unclear how to properly set data
data type is Object
Is there a way to use convenient Lombok's #Builder with given mapping? What would be the simpler and better way to map dto to entity?
Service:
#Service
public class FilterService {
private Condition convertConditionDtoToEntity(ConditionDto conditionDto) {
Type type = typeRepository.findFirstByName(conditionDto.getType())
.orElseThrow(UnsupportedOperationException::new);
Clause clause;
if (conditionDto.getClause() != null) {
clause = clauseRepository.findFirstByName().orElseThrow(UnsupportedOperationException::new);
}
if (conditionDto.getType().equals("amount")) {
return AmountCondition.builder().type(type).data(???).build();
} else if (conditionDto.getType().equals("title")) {
return TitleCondition.builder().type(type).clause(clause).data(???).build();
} else if (conditionDto.getType().equals("date")) {
return DateCondition.builder().type(type).clause(clause).data(???).build();
} else {
throw new UnsupportedOperationException();
}
}
}
Condition
#Getter
#SuperBuilder
#AllArgsConstructor
#NoArgsConstructor
#Entity
#Inheritance(strategy= InheritanceType.TABLE_PER_CLASS)
public abstract class Condition {
#Id
#GeneratedValue
private long id;
#ManyToOne
private Filter filter;
#Getter
#ManyToOne
public Type type;
public abstract Object getData();
}
DateCondition
#Data
#SuperBuilder
#NoArgsConstructor
#AllArgsConstructor
#Entity
public class DateCondition extends Condition {
#Column
int clauseId;
#Column
#Temporal(TemporalType.DATE)
Date date;
#Getter
#ManyToOne
private Clause clause;
#Override
public Object getData() {
return date;
}
}
TitleCondition
#Data
#SuperBuilder
#NoArgsConstructor
#AllArgsConstructor
#Entity
public class TitleCondition extends Condition {
#Column
int clauseId;
#Column
String title;
#Getter
#ManyToOne
private Clause clause;
#Override
public Object getData() {
return title;
}
}
AmountCondition
#Data
#SuperBuilder
#NoArgsConstructor
#AllArgsConstructor
#Entity
public class AmountCondition extends Condition {
#Column
int amount;
#Override
public Object getData() {
return amount;
}
}
Clause
#Data
#Builder
#NoArgsConstructor
#AllArgsConstructor
#Entity
public class Clause {
#Id
#GeneratedValue
private long id;
#Column
String name;
#OneToMany(mappedBy = "clause")
private Set<Type> types = new HashSet();
}
Type
#Data
#Builder
#NoArgsConstructor
#AllArgsConstructor
#Entity
public class Type {
#Id
#GeneratedValue
private long id;
#Column
String name;
#ManyToOne
private Clause clause;
#OneToMany(mappedBy = "type")
private Set<Condition> conditions;
}
I have two forms that I use a lot and save a lot of time.
first: transform your model into json and convert the json to object the Mapper class (this link will help https://www.baeldung.com/jackson-object-mapper-tutorial)
second: spring has some cool functions about it. an example would be the BeanUtils.copyProperties function (source, target);
data problem: the data field does not exist for this reason you do not need to set it.
Another problem that I was able to notice is that their properties are all defaulted so set them as private.

Dynamo DB mapper not saving base class elements to DB when invoked on child class

The problem is that I am not able to save base class members to DB on invoking .save() on child class.
I have two classes class A, class B, I have three common members in both these class creationTimestamp, lastUpdatedTimestamp, version, as these were common I thought I will move them in a base class lets say Class C. But when I do mapper.save() on object of class A, I do not get the members of class C in DB.
#Getter
#Setter
#DynamoDBDocument
#EqualsAndHashCode
#NoArgsConstructor
abstract class C {
#DynamoDBVersionAttribute
private Long version;
#DynamoDBAutoGeneratedTimestamp(strategy = DynamoDBAutoGenerateStrategy.CREATE)
#DynamoDBTypeConvertedTimestamp
private Long creationTimestamp;
#DynamoDBAutoGeneratedTimestamp(strategy = DynamoDBAutoGenerateStrategy.ALWAYS)
#DynamoDBTypeConvertedTimestamp
private Long lastUpdatedTimestamp;
}
Class A:
#Data
#Builder
#NoArgsConstructor
#AllArgsConstructor
#EqualsAndHashCode(callSuper = true)
#ToString(callSuper = true)
#DynamoDBTable(tableName = "A")
public class A {
private String id;
}
Now if I do mapper.save() on object of class A it only saves id to db.
A a = A.builder().id("random").build();
mapper.save(a);
Rather it should have showed version, creationTimestamp, lastUpdatedTimestamp, id any ideas what am I doing wrong here?
Your class A needs to extend class C
#Data
#Builder
#NoArgsConstructor
#AllArgsConstructor
#EqualsAndHashCode(callSuper = true)
#ToString(callSuper = true)
#DynamoDBTable(tableName = "A")
public class A extends C {
private String id;
}

Why does jpa not create table?

I have some classes in my java spring boot project. I use jpa and xampp for localhost. All the Entity classes work and create tables for every #Entity class. But this class does not work. Why?
#AllArgsConstructor
#NoArgsConstructor
#Data
#Entity
public class Match {
#Id
private String matchId;
#Enumerated
private MatchType matchType;
}
Try this:
#AllArgsConstructor
#NoArgsConstructor
#Data
#Entity
#Table(name = "\"Match"\")
public class Match {
#Id
private String matchId;
#Enumerated
private MatchType matchType;
}
More general, if you set
hibernate.globally_quoted_identifiers=true
every identifier gets quoted.

Categories

Resources