capture of ? using Lombok builder - java

I have this class
public class Hostel extends Hotel<Book> {
}
and this other one
#Data
#AllArgsConstructor
#NoArgsConstructor
#EqualsAndHashCode(of = { "id" })
#SuperBuilder(toBuilder = true)
#JsonInclude(NON_NULL)
public class Hotel<T> {
...
}
but when I do
Hostel hostel = Hostel.builder().build();
I got this compilation error
Required type: Hostel
Provided:
capture of ?

You don't have any annotations on Hostel. Hostel.builder() is really a masquerading Hotel.builder().
So the assignment would have to be
final Hotel<?> build = Hostel.builder().build();
Or more accurately (making static methods subject to inheritance was IMO a mistake)
final Hotel<?> build = Hotel.builder().build();
You probably want to add some Lombok annotations to the child class.

Related

Problem in Serialization java spring boot

I have a problem in serialization.
This is my DTO class:
#Data #AllArgsConstructor #NoArgsConstructor
public class ChoicesResponseDTO extends ResponseDTO {
private Long idR;
private ChoicesResponseType choicesResponseType;
private QuestionDTO questionDTO;
}
and this is my scheme from swagger:
ChoicesResponseDTO{
type string
idR integer($int64)
choicesResponseType stringEnum:
Array [ 3 ]
questionDTO QuestionDTO{
idQ integer($int64)
contentQ string
ordreQ integer($int32)
}
}
The problem that if I want to add a new ChoicesDTO, it asks me to add a whole new question in it but I just want to add only the id of the question.
Thanks.
Lombok annotations #AllArgsConstructor #NoArgsConstructor generates constructors for you:
public ChoicesResponseDTO(Long idR, ChoicesResponseType choicesResponseType, QuestionDTO questionDTO)
public ChoicesResponseDTO();
If you want :
public ChoicesResponseDTO(Long idR)
code it yourself or set idR as NonNull or final and add #RequiredArgsConstructor to your class (not compatible with #NoArgsConstructor I guess).

Assign custom lombok builder method as singular handler

I have the following table class which makes usage of #Builder Lombok annotation with a custom builder class:
#Builder
public class MyTable {
...
public static class MyTableBuilder {
public void entry(final MyEntry myEntry) {
...
}
}
}
In another class that is composed by MyTable I would like to make usage of #Builder + #Singular annotations so that I can build TableOwner instances specifying entry by entry.
#Builder
public class TableOwner {
#Singular("entry")
private final MyTable entries;
}
TableOwner.builder()
.entry(...)
.entry(...)
.entry(...)
.build()
However the #Singular annotation on entries results the error "Lombok does not know how to create the singular-form builder methods for type 'MyTable'; they won't be generated.".
Is there a way I can point to MyTableBuilder#entry method as the singular handler for entries?

What is the class type of a #Builder object before calling build()?

I have done this before but forgot and couldn't find the answer easily online.
Let's say I have lombok on a POJO like
#Builder
#NoArgsConstructor
class Car {
private int gallons;
private int wheels;
private String name;
}
and I want to use the builder notation in some logic
public Car getCar(boolean isNew) {
<I dont know what type to put here> carBase = Car.builder().wheels(4);
if(!isNew) {
return carBase.gallons(10).build();
}
else {
return carBase.gallons(0).build();
}
}
What type should I use to fill in?
Okay, so I was actually running into this error Why is Lombok #Builder not compatible with this constructor? which was breaking my #Builder class.
Apparently lombok will generate a static nested class in the class annotated with #Builder called <classname>Builder, so to answer my original question there would be a valid class called Car.CarBuilder.

Best way to initialise fields in a Class without boilerplate code

I have a PivotModel class which I will initialise using the new keyword.
PivotModel pivotModel = new PivotModel()
When pivotModel gets initialised, all the dependant fields(model1, model2,cell1,cell2) should get initialised with new object but not to null.
I wanted to initialise all the fields and the fields of dependant classes without using new constructor. I don't want to have boilerplate code.
If you have any standard practice of way doing it, post it here. I am also using lombok in my project.
public class PivotModel {
#Getter
#Setter
private Model1 model1;
#Getter
#Setter
private Model2 model2;
private Model3 model3 = new Model3() -----> Dont want to initialise this way for these fields
}
public class Model1 {
private Map<String,Cell> cell1;
private Map<String,Cell> cell2;
private Map<String,Cell> cell3;
------ will have some 10 fields here
}
It seems that you are using Lombok project in your java project you can add #Getter #Setter above your class Scope, Lombok also provides Constructor Annotation, so Just type above your class Scope #AllArgsConstructor
so you class Should be like this
#Getter
#Setter
#AllArgsConstructor
public class PivotModel {
private Model1 model1;
private Model2 model2;
}
#Getter
#Setter
#AllArgsConstructor
public class Model1 {
private Map<String,Cell> cell1;
private Map<String,Cell> cell2;
private Map<String,Cell> cell3;
}
For initialization, I would recommended Builder Pattern.
//keep your initialization logic in builder class and use build()/create() wherever required. Let's say:
Class Pivot{
// Note: this have only getters for members
//inner builder class
PivotModelBuilder{
//Note: all setter will be part of builder class
/**
* method which return instantiated required object.
*/
public PivotModel build(){
return new PivotModel(this);
}
}
}
//access initilization code as:
PivotModel pivot = new Pivot.PivotModelBuilder().build()
Adding referral link: https://www.javaworld.com/article/2074938/core-java/too-many-parameters-in-java-methods-part-3-builder-pattern.html
(You can search more about builder pattern and it's implementation online)
Limitations:
However, it's good way to initialize/create bean, but, you might find duplication of member fields in both Parent and builder class.

#Inheritance TABLE_PER_CLASS criteria strange behavior

In my application I have a mapping like this
#MappedSuperclass
public abstract class Base implements Serializable {
#Entity
#Table(name = "LevelOne")
#Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class LevelOne extends Base {
#Entity
#Table(name = "LevelTwo")
public class LevelTwo extends LevelOne {
#Entity
#Table(name = "LevelThree")
public class LevelThree extends LevelTwo {
The tables are created in the DB as expected. The problem I have comes when I try to create a query like this:
session.getCurrentSession().createCriteria(LevelOne.class, "levelOne"). [..] .list();
I get results from all the other LevelX tables not only from the LevelOne Table.
I'm not sure if this behavior is expected or not or if my mapping has an error by not using the an abstract class with the "#Inheritance" annotation, however I would need to get only the "LevelOne" results.
How I could get them?
Yes, it's an expected behaviour. If you need LevelOne only, add a restriction on the implicit class property:
session.getCurrentSession()
.createCriteria(LevelOne.class, "levelOne")
.add(Restrictions.eq("class", LevelOne.class))
. [..] .list();

Categories

Resources