I have a class lets say A. It has few non-null parameters. I am using lombok #NonNull and lombok #Builder. From documentation seems like Builder generates the not null check for parameters.
The other side of story is while retrieving A from DB using hibernate list it is throwing exception saying that A is missing no-arg constructor.
I have no idea on this. I have not defined any constructor for A except for #builder and #NonNUll checks for few parameters. Any idea whats going wrong?
I found solution. Though it seems like a work around.
Adding #NoArgsConstructor #AllArgsConstructor and #builder seems good. Hibernate and builder both can happily work toegther with this
Add the #NoArgsContructor to your class.
Hibernate uses this constructor and then sets the properties.
When you're using #Builder, i think Lombok is generating a constructor that is not the no args one.
Related
I have a use case where I don't want to use the #Builder on the class itself, so I created method based builder like this:
#Builder(builderMethodName = "carBuilder")
public static Car build(int speed, String brand){
Car car = new Car();
car.setSpeed(speed);
car.setBrand(brand);
return car;
}
But how can I handle when the given class has ton of fields (over ~20).
Should I really specify them as parameters and invoke the setters by hand?
Couldn't just lombok generate them automatically based on the type?
Currently this is not possible because Lombok avoids inspecting types from elsewhere on the classpath when processing a file.
What's your reason for not adding #Builder to the class itself? If you can describe a common use case for that, you or someone else might be able to add this ability to Lombok. However, currently I can't see any good reasons for this. Most libraries should be relatively easy to use already and if its your own code, why not just add Lombok?
Also the main reason I add #Builder is because I want my classes to be immutable - given that the actual object is still mutable here, why use builder rather than the setters?
#Data
public abstract class B {
private final String str;
}
#Data
public class A extends B{
private final String s;
}
Data on class A complains in intellij, but the codes can get compiled successfully through command line, not sure what to do
One problem is that #Data is meant for mutable data and there's nothing mutable in your classes. So using #Data is simply wrong... and whether it compiles or not doesn't really matter.
If you want mutable data, then remove the final field. For immutable data, make all fields final and use #Value. Sometimes, partially mutable data is needed, but I try hard to avoid it as it's confusing (some fields can be set, some can't) and they provide disadvantages of both.
The other problem is that Lombok can't access class hierarchies. With B having a final field, you need it to be initialized in the constructor, which means that A's constructor has to call a non-default constructor. This isn't possible with Lombok. There's #Superbuilder in Lombok, which is about the only feature of Lombok dealing well with class hierarchies.
The #Data annotation does not add a default contructor.
Try to add a #NoArgsConstructor to your Base Class B to generate a default constructor with Lombok.
You can also read up what #Data actually means here.
This does not event compile. In Intellij, when you are not sure what is the problem with lombok code, you can open class in which you are unsure, go on Refactor -> Delombok -> All lombok annotations and you will see what lombok actually create for you.
I want to use lombok in a enum, but I can't find the annotation to generate the constructor. I checked the Lombok manual that it shows there should be a annotion named #XArgsConstructor,but I can't find it, any advice ? thanks.
X in #XArgsConstructor is just a placeholder for No, Required or All.
The real annotations are #NoArgsConstructor, #RequiredArgsConstructor and #AllArgsConstructor. Pick one of these (I'd go for #AllArgsConstructor by default), and it'll work.
After scouring the Lombok feature-list and in particular the documentation for the Getter/Setter and #Value annotations I have not been able to find any setting that suppresses the code generated by #Getter.
In practice, #Value is shorthand for: final #ToString #EqualsAndHashCode #AllArgsConstructor #FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) #Getter
This is important as I do not want to leak references to objects that are themselves mutable.
Effective Java references this type of issue in "Item 39: Make defensive copies when needed". It seems that #Wither could partly solve this issue by making actual defensive copies but I want to avoid leaking attributes what so ever, regardless of them being mutable.
While it is possible to roll one's own #Value annotation that omits the #Getter I would, of course, prefer not to as that would add unwarranted complexity to the codebase if such a setting already exists.
You could use:
#Value
#Getter(AccessLevel.NONE)
AccessLevel.NONE instructs Lombok to not generate the getters. That's the best you can do right now.
Recently we started make use of Lombok features in our project. we have #Data annotation for the Domain object, due to this running with some exception thrown by hashCode() method provided by Lombok api. Later, when I added #Setter and #Getter instead of #Data, I didn't see any issues.
Question1: Does Lombok #Data override the existing methods in a class like hashCode() and toString()?
Question2: why is hashCode() making problems here?
Yes, #Data implies #EqualsAndHashCode and #ToString. See the #Data documentation.
The generated hashCode() method will call the hashCode methods for all fields. So if one of the values of the fields throws an exception, so will this.
One other scenario is that you have circular object references: If one object has a field that contains an object that has a field that refers to the first object, invoking the hashCode method will trigger a StackOverflow.
Disclosure: I am one of the Lombok developers.