Lombok @SuperBuilder workaround on IntelliJ
Asked Answered
P

3

19

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.

Pretypify answered 24/4, 2019 at 22:41 Comment(2)
The code compiles and runs for me. It is just a false 'error' in IntelliJ which you can ignore until the final plugin version is released. As of Sept 1st 2019, alpha version is released github.com/mplushnikov/lombok-intellij-plugin/releases/tag/…Golly
@SuperBuilder support has made it to release 0.27 of the IntelliJ Lombok plugin.Miki
F
6

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.

Fuscous answered 5/5, 2019 at 19:20 Comment(0)
E
4

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();
Empyema answered 30/7, 2019 at 13:34 Comment(0)
L
2

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();
Lenity answered 28/11, 2019 at 4:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.