Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lombok @SuperBuilder workaround on IntelliJ

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.

like image 264
drenda Avatar asked Apr 24 '19 22:04

drenda


People also ask

Does Lombok work with IntelliJ?

As of IntelliJ version 2020.3, we don't need to configure the IDE to use Lombok anymore. The IDE comes bundled with the plugin. Also, the annotation processing will be enabled automatically.

What is Lombok Tobuilder?

Overview. Project Lombok's @Builder is a helpful mechanism for using the Builder pattern without writing boilerplate code. We can apply this annotation to a Class or a method. In this quick tutorial, we'll look at the different use cases for @Builder.

What is Lombok SuperBuilder?

The @SuperBuilder annotation produces complex builder APIs for your classes. In contrast to @Builder , @SuperBuilder also works with fields from superclasses. However, it only works for types. Most importantly, it requires that all superclasses also have the @SuperBuilder annotation.


2 Answers

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.

like image 80
desr Avatar answered Sep 18 '22 11:09

desr


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();
like image 23
Andrii Polokh Avatar answered Sep 17 '22 11:09

Andrii Polokh