Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generating equals/hashCode implementation but without a call to superclass, even though this class does not extend java.lang.Object

Tags:

java

lombok

I am getting below error while using lombok and even it doesn't allow me to set id and version while creating student instance.

Multiple markers at this line
    - overrides com.example.demo.IModel.canEqual
    - Generating equals/hashCode implementation but without a call to superclass, even though this class does not extend java.lang.Object. If this is 
     intentional, add '@EqualsAndHashCode(callSuper=false)' to your type.
    - overrides com.example.demo.IModel.hashCode
    - overrides com.example.demo.IModel.toString
    - overrides com.example.demo.IModel.equals

IModel

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class IModel {
    private String id;
    private String version;
}

Student

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Student extends IModel{
    private String firstName;
    private String lastName;
}

enter image description here

In the main method, it doesn't allow me to set the value of Id and version field

Student s = Student.builder().firstName("Adam").lastName("Kerr").build();

Edit-1 @sfiss - As suggested, now I changed like below, but now I am not able to set firstName and lastName, only cab set id and version

Student.java

@Data
@Builder(builderMethodName = "studentBuilder")
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
public class Student extends IModel {
    @NotEmpty(message = "{email.notempty}")
    @Email
    private String firstName;
    private String lastName;

    public Student(final String firstName, final String lastName, final String id, final String version) {
        super(id, version);
        this.firstName = firstName;
        this.lastName = lastName;
    }
}

IModel.java

@Builder
@Data
@NoArgsConstructor
@AllArgsConstructor
public class IModel {
    private String id;
    private String version;
}
like image 362
PAA Avatar asked Jun 13 '19 15:06

PAA


People also ask

Does @data generate equals and hashCode?

The annotation @Data with inheritance produces the next warning: Generating equals/hashCode implementation but without a call to superclass, even though this class does not extend java.

How do you override equals method in Lombok?

If you need to write your own equals methods, you should always override canEqual if you change equals and hashCode . NEW in Lombok 1.14. 0: To put annotations on the other parameter of the equals (and, if relevant, canEqual ) method, you can use onParam=@__({@AnnotationsHere}) . Be careful though!

What is the relationship between hashCode () and equals () method in java?

If two objects are equal(according to equals() method) then the hashCode() method should return the same integer value for both the objects. But, it is not necessary that the hashCode() method will return the distinct result for the objects that are not equal (according to equals() method).

What is the use of @EqualsAndHashCode?

The @EqualsAndHashCode annotation instructs the compiler to execute an AST transformation which adds the necessary equals and hashCode methods to the class. The hashCode() method is calculated using Groovy's HashCodeHelper class which implements an algorithm similar to the one outlined in the book Effective Java.


3 Answers

There are multiple problems here, all of them relating to using lombok with inheritance:

  1. Generating equals/hashCode implementation but without a call to superclass, even though this class does not extend java.lang.Object. If this is intentional, add '@EqualsAndHashCode(callSuper=false)' to your type.

The warning is given by @Data because that usually generates equals/hashcode without the call to super. Fix it by adding @EqualsAndHashCode(callSuper = true).

  1. The @Builder gives you a compile warning because it will generate two static methods with the same name in both the super- and the subclass. Fix it by defining @Builder(builderMethodName = "studentBuilder") on Student.

  2. You won't be able to set superclass properties on you studentBuilder because your superclass and subclass have a default constructor. Fix it by creating a constructor and moving the @Builder annotation to it (i.e. annotate the constructor with @Builder, not the class):

Code:

@Builder(builderMethodName = "studentBuilder")
public Student(
    final String firstName,
    final String lastName,
    final String id,
    final String version) {
    super(id, version);
    this.firstName = firstName;
    this.lastName = lastName;
}

Call your builder with the correct method (IModel.builder() vs Student.studentBuilder()):

Student.studentBuilder().firstName("Name").build();

I also want to add some improvements to the above solution. While I like lombok as a tool (I really don't need to read that much boilerplate), the first solution to preventing boilerplate is to think whether you need all those getters and setters and ask yourself these questions:

  • Do you want bags of data? It is fine for some use cases, in others you want objects more in the sense of OOP, i.e. don't expose your state but behavior.

  • Do you really need mutability? If not, prefer @Value.

  • Do you really need both constructor types (especially the no-args-constructor)? They are part of the problem here. Sometimes you need them for frameworks (proxies, reflection, ...) to work properly.

  • More specific to your code: You prefixed the superclass with "I" but it is not an interface. If it is meant as an abstract class, declare it abstract and don't give it a @Builder.

like image 151
sfiss Avatar answered Sep 30 '22 15:09

sfiss


You can use @sfiss solution

or

You can use @Getter and @Setter annotations instead of @Data annotation.

like image 35
Oguzhan Cevik Avatar answered Sep 30 '22 15:09

Oguzhan Cevik


The warning from building a Spring Boot project

When I built my Spring boot project, I got 20 warnings about a same thing. The warning shows: Generating equals/hashCode implementation but without a call to superclass

Description of the warning

This warning is from lombook, it happens when we inherit a child class from parent class by using @Data @ToString @EqualsAndHashCode, IDE will trigger the warning: Generating equals/hashCode implementation but without a call to superclass .

Solution

There are two solutions:

  1. add annotation @EqualsAndHashCode(callSuper = true) on the class
  2. create lombook config file in the project root path: src/main/java. Note: this solution requires the version of lombook > 1.14.

I recommend the solution 2, since you will not need to add the annotation to all the required classes.

To impletement the solution, you need to create lombok.config in the path of src/main/java. If you have more than one packages, you may need to create multiple config files.

The content of the config file includes:

config.stopBubbling=true
lombok.equalsAndHashCode.callSuper=call

When we rebuild our project, you will not get these warnings anymore.

Cheers!

like image 3
William Yu Avatar answered Sep 30 '22 15:09

William Yu