Builder annotates a private class? - java

#Data
#Builder
public class ClassA {
private ClassB b;
private String createdBy;
private class ClassB {
String name;
int version;
}
}
Hi I want to create ClassA in another java file this way:
ClassA.builder().createdBy("Alex")
.b(ClassB.builder()
.name("Game")
.version(2).build())
.build();
Is this possible for private class classB?
Thx

I recommend as below:
#Data
#Builder
public class ClassA {
private ClassB b;
private String createdBy;
#Builder
#Data
static class ClassB {
String name;
int version;
}
}
if you want unvisible ClassB it is impossible. and To using #Builder on inner class , class must be static class

private modifier means that the variable is only visible for this class only. So if you create private class B inside class A it means B only visible for A.
As #sweeper said in the comment, you cannot use class B in another file / class except for class A.
If you still want to use that way, you can create class B independently.
ClassA.class
#Data
#Builder
public class ClassA {
private ClassB b;
private String createdBy;
}
ClassB.class
#Data
#Builder
class ClassB {
String name;
int version;
}

Related

How to fill if i use mapstruct and generic type in java

I would like to fill this fields with mapstruct but i don't know how to fix it because i never use mapstruct with generic type thanks for any attentions
#Data
#ToString
public class SvGateRequest<T> {
public SvGateRequest(String method, T params) {
this.method = method;
this.params = params;
}
private String jsonrpc="2.0";
private String method;
private Long id = System.currentTimeMillis();
private T params;
#Data
#ToString
#Builder
#DynamicUpdate
#DynamicInsert
public static class CardNew{
private Card card;
private CardVerify otp;
#Data
#ToString
#Builder
public static class Card{
private String pan;
private String expiry;
}
#Data
#ToString
#Builder
public static class CardVerify{
private Long id;
private String code;
}
}
}
it is my dto class which take params to fill FillCard class but sometimes instead of FillCard class i can use fill CardVerify class with another dto class thats why i try optimize my code
#Data
#JsonInclude(JsonInclude.Include.NON_NULL)
public class FillCard {
private String pan;
private String expiry;
}
whether it is preferable to use generic types with mapstruct itself or not

How to use specific value of enum in swagger schema using annotation

Here are 3 simple Java classes:
#Getter
#Setter
public class Animal {
protected String name;
protected Integer age;
public enum AnimalType{
ANGRY,
FUNNY
}
}
#Getter
#Setter
public class Cat extends Animal{
private AnimalType type=AnimalType.ANGRY;
}
#Setter
#Getter
public class Dog extends Animal{
private AnimalType type=AnimalType.FUNNY;
}
What do I need to do so that swagger generates something like this?
type* AnimalType string
value= FANNY
Enum:
>Array[2]
Is there any way to do it? I need to add ENUM for all classes and specific value of this enum for each class.

How to create a constructor/builder for nested Java classes?

Let's say I want to mock a class with the following structure, for testing purposes:
#Data
public class Street() {
private House house;
#Data
static class House {
private List<Room> rooms;
}
#Data
static class Room {
private Door door;
}
#Data
static class Door {
private String material;
}
}
What would be the best way to concisely create a Street object, containing a House that has a Room with a wooden door?
I was thinking of adding a Lombok #Builder annotation to the Street class, but discovered I would also need builders for each of the nested classes, and was wondering if there would be a cleaner way to achieve this.
Use #SuperBuilder from lombok project
Assume you have :
#Getter
#SuperBuilder
public class Parent {
private final String parentName;
private final int parentAge;
}
#Getter
#SuperBuilder
public class Child extends Parent {
private final String childName;
private final int childAge;
}
#Getter
#SuperBuilder
public class Student extends Child {
private final String schoolName;
}
Then you can create a new Student like this :
Student student = Student.builder()
.parentName("Andrea")
.parentAge(38)
.childName("Emma")
.childAge(6)
.schoolName("Baeldung High School")
.build();
Reference : https://www.baeldung.com/lombok-builder-inheritance#lombok-builder-and-inheritance-1
My only suggestion is this:
public class Street {
private House house;
private Room room;
private Door door;
public class House{
//build class House
}
public class Room{
//build class Room
}
public class Door{
//build class Door
}
public Street(House house, Room room, Door door) {
this.house = new House();
this.room = new Room();
this.door = new Door();
}
}
and then you can work inside the Street class with the objects you have to access methods of the other little classed nested into Street

Extending class with changing field requirements

Let's have example base class
#Data
#NoArgsConstructor
#AllArgsConstructor
public class User {
#JsonProperty("login")
private String login;
#JsonProperty("password")
private String password;
#JsonProperty("additionalData")
private String additionalData;
}
and second one that extends User class
#Data
#NoArgsConstructor
#AllArgsConstructor
public class EnhancedUser extends User {
#NotNull
#JsonProperty("additionalData")
private String additionalData;
}
I but It doesn't work because when I create instance of EnhancedUser class field additionalData can be null.
Any idea?
Look:
public class Sample {
public static void main(String[] args) {
EnhancedUser enhancedUser = new EnhancedUser();
enhancedUser.setAdditionalData("TAMU");
enhancedUser.setLogin("ANY");
enhancedUser.setPassword("ANY");
System.out.println(enhancedUser);
System.out.println(enhancedUser.getAdditionalData());
}
#Data
#NoArgsConstructor
#AllArgsConstructor
public static class User {
private String login;
private String password;
private String additionalData;
}
#EqualsAndHashCode(callSuper = true)
#Data
#NoArgsConstructor
#AllArgsConstructor
#ToString(callSuper = true)
public static class EnhancedUser extends User {
#NotNull
private String additionalData;
}
}
And the result of printlnis
Sample.EnhancedUser(super=Sample.User(login=ANY, password=ANY, additionalData=TAMU), additionalData=TAMU)
TAMU
You do realize that you actually have 2 fields "additionalData"? Since you can't override fields but merely hide them. And this is a huge nono anti-pattern in general.
Either you rename your field or you think of a more approriate implementation, like implementing this logic yourself with and a constructor argument and a call of the additionalData setter from your constructor.

Inheritance for builders in lombok

I was trying to use lombok for my project.
I have a class A:
#Data
#Builder
public class A {
Integer a1;
}
and a class B:
#Data
public class B extends A {
Integer b1;
#Builder
public B(Integer b1, Integer a1) {
super(a1);
this.b1 = b1;
}
}
I am getting an error saying builder() in B cannot override builder() in A, as return type in BBuilder is not compatible with return type in ABuilder.
Is there some way to do this using lombok?
I do not want to write the complete builder for for B, unless I don't have any other option.
PS: I have given explicit constructor for class B due to Issue.
I tried searching, but I could not find a good solution for the same.
Here we just need to call super of the builder.
#Data
public class B extends A {
Integer b1;
#Builder
public B(Integer b1, Integer a1) {
super(a1);
this.b1 = b1;
}
public static class BBuilder extends ABuilder{
BBuilder() {
super();
}
}
}
If you are using Lombok 1.18.4 along with IntelliJ, following code shall work for you:
#Data
#Builder
class A {
Integer a1;
}
#Data
class B extends A {
Integer b1;
#Builder (builderMethodName = "BBuilder")
public B(Integer b1, Integer a1) {
super(a1);
this.b1 = b1;
}
}
public class Main {
public static void main(String[] args){
System.out.println(B.BBuilder().a1(1).b1(1).build());
}
}
One a side note, #SuperBuilder annotation didn't work in IntelliJ at time of writing this answer. If you have multiple level of inheritance, please avoid Lombok or it will make your Java models messy.
Lombok has introduced experimental features with version: 1.18.2 for inheritance issues faced with Builder annotation, and can be resolved with #SuperBuilder annotation
Please use lombok version: 1.18.2, #SuperBuilder annotations in child/parent class
Both child and parent should be marked with #SuperBuilder.
Having both parent and child as #Builder won't work.
Parent class A:
#Data
#SuperBuilder
public class A {
Integer a1;
}
Child class B:
#Data
#SuperBuilder
public class B extends A {
Integer b1;
}
After hours of hacking at this, I found a viable solution without using the #SuperBuilder. Consider an example -
public class A{
int x;
#Builder(toBuilder = true)
public A(int x){
this.x = x;
}
public static class ABuilder{
protected ABuilder(){} //Note this is important, otherwise BBuilder won't be able to access private no-args constructor of ABuilder
}
}
public class B extends A{
#Builder(builderMethodName="BBuilder", toBuilder=true)
public B(int x){
super(x);
}
public static class BBuilder extends ABuilder{
BBuilder(){
super();
}
}
}
public static void main(){
B obj = new B();
//we can use the existing obj as obj.toBuilder().x(5).build();
//this will return an object of B and not A
}
P.S : I am not sure if #SuperBuilder is an experimental feature still ; so didn't want to take chances

Categories