I've a class Product:
#Data
#SuperBuilder
public class Product {
private String name;
private String manufacturer;
}
and an extended class
#Data
#SuperBuilder
public class Frame extends Product{
private String model;
}
I'm trying to create a Frame object using the builder:
return Frame.builder()
.name("Frame ABC")
.manufacturer("Manufacturer")
.model("Model 1")
.build();
I'm using IntelliJ 2019.1.1 with Lombok plugin but unfortunately the compiler marks as error the .name() and .manufacturer() methods.
I saw this issue opened and I'm wondering if there is a workaround to make my code to work.
No, not until the issue is resolved.
Its a chicken and egg issue. Until the classes with the #SuperBuilder annotations are compiled, the actual generated builder methods do not exist. The plugin (once updated/fixed) works with the IDE for these methods so that even though they don't exist yet, the plugin tells the IDE what they will be when compilation takes place.
There are ways to 'cheat' but they are all hacks - for example, you could compile your (super)builder classes in their own jar and then import that jar into your project. As you compiled the SuperBuilder classes they now contain all the generated methods, thus the IDE will see the actual methods and will therefore propose them if you try use them. Functional but not very useful... if you need to update the SuperBuilder annotated classes, you now have to compile them each time before the changes become visible. Obviously you could create build tasks to do this for you, but you are always working around the actual issue which is plugin support.
This workaround works for me:
#Data
#AllArgsConstructor
#NoArgsConstructor
public class Product {
private String name;
private String manufacturer;
}
#Data
#NoArgsConstructor
public class Frame extends Product{
private String model;
#Builder
public Frame(String name, String manufacturer, String model){
super(name, manufacturer);
this.model = model;
}
}
The only problem I see is when you have a lot of fields in the class it is becoming annoying to write such constructors, but still I think it worth it cause at the end you can access parent and child fields.
return Frame.builder()
.name("Frame ABC")
.manufacturer("Manufacturer")
.model("Model 1")
.build();
Build with child member fields first, then parent member fields, with a type casting seems to work for me:
return (Frame) Frame.builder()
.model("Model 1")
.name("Frame ABC")
.manufacturer("Manufacturer")
.build();
Related
I imported everything according to the Projectlombok site into my project.
I wonder if it is possible to call the getters and other things generated by Lombok right in the source code? I've tested that the JSON serializer can access these after compiling, but I can't use them in the project.
For example:
#Getter
class Person {
String name;
}
class MyClass {
void f(Person p) {
p.getName(); // doesn't compile for me
}
}
Tell me if I am wrong that Lombok can be used for this purpose.
So looking at my class files the getters/setters are being generated just fine, but I'm trying to write a copy method that looks like this in the same jar.
#Data
public class SoftwareVersions {
private String applicationVersion;
void copyTo( MonitorFoleyConnection mfc ) {
mfc.setApplicationVersion( applicationVersion );
}
}
in gradle
annotationProcessor("org.projectlombok:lombok:1.+")
compileOnly("org.projectlombok:lombok:1.+")
is it possible to get intellij to recognize the existance of this method?
Yes, you have. You just need to do two things:
Install the Lombok Plugin for Intellij:
Enable the annotation processing:
It seems that #RequiredArgsConstructor not working in the code below. Why is it?
import java.io.Serializable;
import lombok.Data;
import lombok.RequiredArgsConstructor;
#Data
#RequiredArgsConstructor
public class User implements Serializable {
private String username;
/*public User(String username) {
this.username = username;
}*/
private static final long serialVersionUID = 8043545738660721361L;
}
I get the error:
javax.faces.el.EvaluationException: java.lang.Error: Unresolved compilation problem:
The constructor User(String) is undefined
For some reason seems it does work for other domain class in which no constructor defined but instead used the #RequiredArgsConstructor annotation.
According to Documentation,
Required arguments are final fields and fields with constraints such as #NonNull.
You need to make username as #NonNull
#NonNull private String username;
And you need to make them final too.
It's also worth noting for future readers that #Data also provides #RequiredArgsConstructor, so using both annotations isn't necessary :)
Did you installed Lombok plugin in IntelliJ?
If not then
File -> Settings -> Plugins: Search for Lombok (CodeStream) version.
Restart the IDE and it should be fixed.
Double Check:
You have Lombok library installed using Maven or Gradle.
Enabled Annotation Processors from IntelliJ IDE from File -> Settings: Search for Annotation Processors
#RequiredArgsConstructor
> Generates a constructor with required arguments. Required arguments
are final fields and fields with constraints such as #NonNull.
> Complete documentation is found at the project lombok features page
for #Constructor.
> Even though it is not listed, this annotation also has the
*`onConstructor`* parameter. See the full documentation for more details.
Lombok library
To use the #RequiredArgsConstructor, the variable has to be final and it will create the values in constructor automatically
private final String username;
Try changing project/module JDK to 1.8.
Project Structure -> Project Settings->Project SDK and Project Language Level
The argument fields for #RequiredArgsConstructor annotation has to be final. So this fix will work:
private final String username;
The IDE IntelliJ makes the variable grey (inactive status) when final keyword missed, which is very helpful to detect this kind of mistake.
I'm using lombok in intellij, and have the plugin installed.
My problem is that when I use the #Date notation in my class, only that class can see the methods created by lombok. So if my class declaration looks like this:
#Document
#Data
public class dbDocument {
#Id
private String uniqueId;
And the method
public String testGetter (dbDocument doc) {
return doc.getUniqueId;
}
Will work inside the dbDocument class, but not in any other class. (where I get a Java: cannot find symbol error)
How can I fix/debug this?
Oops.
Looks like I was spelling the method wrong while invoking it. Nothing to see here.
When I have added this following code to my project
Form<User> filledForm2 = userSignupForm.bindFromRequest();
It has stopped working by showing an error message which states:
Execution exception
[IllegalStateException: JSR-303 validated property 'Password' does not have a corresponding accessor for data binding - check your DataBinder's configuration (bean property versus direct field access)]
My User class was like that:
class User{
String username;
String Password;
}
Now how can to check/modify DataBinder's configuration in java play framework?
Actually this shouldn't be happening, as Play automatically generates getters and setters, see Guillaume's comment.
Therefore it's possible that your IDE is causing issues e.g. Guillaume's comment re Eclipse. Or that your sbt cache is corrupt and needs cleaning, which you can do with play clean-all (read about it here)
By the way, changing your Password attribute to password may have caused the cache to be re-generated and therefore fixed the issue.
Update:
For more recent versions of Play that use activator, it seems the following are the the up-to-date equivalents:
activator clean and activator clean-files
My environment is Mac OS X 10.9.5 and run CentOS 7 with Vagrant. On CentOS the same problem happended, but on Mac OS didn't. Play Framework version is 2.3.8.
The commnad below didn't work in my case:
activator clean
activator clean-files
Though it's so weird, I had to define getter and setter to work Play Framework on CentOS7 successfully as following:
#Entity
public class Message extends Model{
#Id
public long id;
#Constraints.Required
public String name;
//Add getter and setter to work successfully...
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
I've fixed this issue by using activator clean && activator clean-files before doing activator dist
I got the same error trying to validate int field in POJO using
#Min(value = 0).
Solved by putting the annotation on getter in combination with #Valid in my bean.
Had the same issue...
To remove this error, you should define your variables as public.
class User{
public String username;
public String password;
}