The introduction

At noon today, I was wearing headphones to roam in the world of code, which was operated in the group @, angrily asked me whether I had deleted the user data recently. I must have politely replied no? Production of the data I how can casually can delete, but the company’s red line, and I also do not have the database delete permission, but some query permission. Hurriedly boarded the fortress machine, and then to check the production database data, checked the data is still in, frighten dead, data, then it has no problem, does not have a problem with my application, unlock code to check, why without a user data, see the code seems to be nothing under a logical problem is relatively simple, Query data directly from DB through paging to the front end, and the front end is responsible for display, no complicated logic. I thought it must be the problem of the front end, and it must be that he did not show the data, so I immediately threw the problem to him, and asked him to help and cooperate to see if it was the problem of the front end. Then I also looked at the code carefully. In less than a minute, the front end said that there was no problem with the data he showed, and all the data were given by the back end. That’s a bug in the back end. What looks like a problem to the naked eye is missing data due to paging. However, this paging plug-in is used all over the company, should not cause problems, can not find the problem can only let the test help to try in the test environment, see if can reproduce.

Test environment replication

We have written a unit test to simulate the production of data, and the logic is as follows:

public static void main(String[] args) {
        Set<UserDTO> userSet = new HashSet<>();
        UserDTO userDTO = new UserDTO();
        userDTO.setId(1);
        userDTO.setUserName("Java financial");

        UserDTO userDTO1 = new UserDTO();
        userDTO1.setId(2);
        userDTO1.setUserName("Java financial");
        userSet.add(userDTO);
        userSet.add(userDTO1);
        System.out.println(userSet.size());
        System.out.println(userDTO1.equals(userDTO));
    }

    @Data
    static class UserDTO extends BaseDTO {
        private String userName;
    }
    @Data
    static class BaseDTO {
        private Integer id;
    }
Copy the code

We can print it outsetThe length of the set is 1,user1anduser2It’s the same. It’s the sameusertheIDIt’s different. Why is it equal? We know that the set can be deduplicated because the operation of the set is done by the operation of the map,settheaddIt’s just callingmaptheputMethod,maptheputMethod I believe you should have gone to the source code, here will not be detailed again, the general process is through the key through the hash algorithm to locate the array index, first judgekeythehashIs it equal? If it is equal, then determine the value of the key is equal. If both are equal, the original value will be overwritten. Our example above is the objecthashandvalueBoth are equal, but our two objectsuser1anduser2It should be different because the ids are different, so why are the columns equal? Let’s take a closer look at the code above, we usedlombokinside@DataAnnotation, we can see what methods this annotation helps us generateWe can see from the above comparison@DataAnnotations help us generate annotations on the class, providing the classGet, set, equals, hashCode, canEqual, and toStringMethod, this annotation is really handy. The one abovebugJust because it generates equals, we can compile the above code and take it toclassInside of itequalsMethod

We can see that the equals method only compares the userName field, which is the field of the current class. It does not compare the fields of the parent class. This is why the two objects are equal.

To solve the problem

  • Manual overrideequalsandhashCodeMethod, this method is definitely not recommended, but we use itlombokJust to free up our hands, make the code cleaner.
  • Add to the class that you are comparing@EqualsAndHashCode(callSuper = true) callSuper = trueIt will include the superclassequalshashCodemethods

We can compare that to plus@EqualsAndHashCode(callSuper = true)And generated without the annotationequalsMethod.The difference is obvious. Yes@EqualsAndHashCode(callSuper = true)I’m going to call the superclassequalsMethod comparison, so this annotation can solve this problem as well.

  • Adding a comment like this does solve the problem, but putting it on top of every class is also a physical task. We can look for other solutions, such as if there is a configuration file setting, and then it will work globally. And finally by looking at the data and finding us we write onelombok.configThe configuration file is placed under the root directory of our projectlombok.equalsAndHashCode.callSuper = callEffect equivalent@EqualsAndHashCode(callSuper = true)In this case, we don’t need to add this comment for every class, so we only need to use it in this project@DataAnnotated classes will be added to it@EqualsAndHashCode(callSuper = true)The configuration file takes effect globally.

conclusion

  • Let’s go back to the above question again, it comes down to the objectequalsMethod, so we need to override it if the business judgment of the custom object is equalhashCodeandequalsMethod, we can pass it when we rewrite itideaAfter generation, it is better to take a look at the generation to see if it meets our business requirements.
  • We operate some common container classes such as Set, Map and so on in our work to implement some of our own business, we still need to look at their source code, such as we use the Set to redo, if we are using custom objects, if not overriddenhashCodeandequalsMethod, to the weight will not be successful, we only understand it, can really use it. In abouthashCodeandequalsAlibaba development manual also has clearly said

  • lombokIt’s nice to use, but there are a few details that need a little attention. Before use, you can generally go to see the content provided by its official website, otherwise there will be baffling problems you do not know how to start. This is a little bit similar to what we usedSpringBootYeah, it’s great to use, but if it’s weirdbugIt’s a headache to solve.
  • Finally, let’s review a few more questions abouthashCodeandequalsWhat are the most common interview questions? The following questions are pretty easy to ask if you’ve actually looked at the source code for HashMap.

When do we need to override methods? Is it okay to override equals and not override HashCode? Equals, == and hashcode()?

The end of the

  • Due to their lack of knowledge, it is hard to avoid mistakes, if you find the wrong place, also hope to leave a message to me to point out, I will correct it.
  • If you think the article is good, your retweet, share, praise, like, comment is the biggest encouragement to me.
  • Thank you for reading. I very much welcome and thank you for your attention.