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.
Related
I am trying of implement a strategy to load from application.properties two values set dinamically depending on condition of income:
# Configuration A
payouts.xxx.by-default.business-name=ABC S.A.S
payouts.xxx.by-default.nit=830109723
payouts.xxx.by-default.account.number=1234567890
payouts.xxx.by-default.account.type=01
payouts.xxx.by-default.account.financial-institute-id=GEROCOBB
payouts.xxx.by-default.BIC=4566
# Configuration B
payouts.xxx.loan.business-name=XYZ S.A.S
payouts.xxx.loan.nit=830109723
payouts.xxx.loan.account.number=1234567890
payouts.xxx.loan.account.type=01
payouts.xxx.loan.account.financial-institute-id=GEROCOBB
payouts.xxx.loan.BIC=344444
So I have 2 class that represented the properties values :
#Data
#AllArgsConstructor
#NoArgsConstructor
#Builder
public class AccountConfiguration {
private String businessName;
private String nit;
private String bic;
private Account account;
}
#Data
#AllArgsConstructor
#NoArgsConstructor
#Builder
public class Account {
private String number;
private String type;
private String financialInstituteId;
}
And also I have other class that represented the configuration class to get the values from application.properties
#Data
#AllArgsConstructor
#NoArgsConstructor
#Builder
#Configuration
#ConfigurationProperties(prefix = "payouts.xxx.loan")
public class PayoutAccountConfiguration {
private AccountConfiguration byDefault;
private AccountConfiguration loan;
public AccountConfiguration getConfiguration(String flag) {
if (flag.equals(PayoutOrderStatus.IN_AUTOMATIC)) {
return loan;
}else{
return byDefault;
}
}
}
And for last in the application class I have anotation to enabled the configuration
#SpringBootApplication
#EnableFeignClients
#EnableConfigurationProperties({AccountConfiguration.class, Account.class})
#Import(EncryptedPropertyConfiguration.class)
public class TestApplication {
/**
* The main method to start the application.
* #param args command-line arguments
*/
public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
}
Now I need that in getConfiguration method there are logic to decided depends on income if return the value by default(Configuration A) or the value personalized (Configuration B). I don't know how do these. Can you help me. giving ideas please.
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
#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;
}
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
I have class:
public class User implements Body {
private Integer userId;
private String userName;
private String emailId;
//getter and setter
}
I want with Jackson mapper exclude Body class because I get error
ObjectMapper mapper = new ObjectMapper();
User user = new User;
String jsonString = mapper.writeValueAsString(user);
How I can convert object to JSON with exclude all extended or implementation class? I need convert only User class without Body
My super class have many public method like this:
public final Enumeration method(String email) {
throw new RuntimeException("Error");
}
public final Object method(String name) {
throw new RuntimeException("Error");
}
Simply annotate the class you are serializing and list the properties to exclude.
#JsonIgnoreProperties({"bodyPropertyA", "bodyPropertyB", "bodyPropertyC"})
public class User implements Body {
private Integer userId;
private String userName;
private String emailId;
}
Try to add a filter to exclude parent fields. Here is a test:
public class JacksonTest {
#Test
public void excludeParent() throws JsonProcessingException {
ObjectMapper objectMapper= new ObjectMapper();
SimpleBeanPropertyFilter theFilter = SimpleBeanPropertyFilter
.serializeAllExcept("name","phone");
FilterProvider filters = new SimpleFilterProvider()
.addFilter("filterPerson", theFilter);
objectMapper.setFilterProvider(filters);
final User user = new User("email1",12);
user.setName("personName");
user.setPhone("12345");
System.out.println(objectMapper.writeValueAsString(user));
}
}
#Data
#AllArgsConstructor
#NoArgsConstructor
#JsonFilter("filterPerson")
class User extends Person{
String email;
int age;
}
#Data
#AllArgsConstructor
#NoArgsConstructor
class Person{
String name;
String phone;
}
console:
{"email":"email1","age":12}
Try this:
#JsonIgnore
public interface HiddenBody extends Body {
}
public class User implements HiddenBody {
//
}
The Liskov Substitution Principle says everything should still compile and execute OK.