0

There is an entity :

@Entity
@Table(name = "menu")
public class Menu {

    @Id
    @SequenceGenerator(name="s_menu", sequenceName="s_menu", allocationSize=1)
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="s_menu")
    @Column(name = "menu_id")
    private int id;

    @Column(name = "gmnu_code")
    private Integer groupeMenu;

    @Column(name = "menu_lib")
    private String lib;

    @Column(name = "menu_ordre")
    private Integer ordre;

    @Column(name = "menu_visible")
    private Integer visible;

    @Column(name = "menu_deleted")
    private Integer deleted;

    @Column(name = "menu_bouton")
    private Integer bouton;

    @Column(name = "menu_parent")
    private Integer parent;

    @Column(name = "menu_controlleur")
    private String controlleur;

    @Column(name = "menu_navigation")
    private String navigation;

    @Column(name = "menu_flag_trace")
    private Integer flag_trace;

    @Column(name = "menu_trace")
    private String trace;

    @ManyToMany(fetch = FetchType.EAGER, mappedBy = "menus")
    @JsonBackReference
    private Set<Role> roles = new HashSet<Role>();

    @Transient
    private int depth;

    @Transient
    private boolean affectedToARole;

    @Transient
    private Environment env;

    public Menu() {
        super();
    }

    public Menu(Integer gmnu_code, String menu_lib, Integer menu_ordre, Integer menu_visible, Integer menu_deleted, Integer menu_bouton, Integer menu_parent, String menu_controlleur, String menu_navigation, Integer menu_flag_trace, String menu_trace) {
        super();
        this.groupeMenu = gmnu_code;
        this.lib = menu_lib;
        this.ordre = menu_ordre;
        this.visible = menu_visible;
        this.deleted = menu_deleted;
        this.bouton = menu_bouton;
        this.parent = menu_parent;
        this.controlleur = menu_controlleur;
        this.navigation = menu_navigation;
        this.flag_trace = menu_flag_trace;
        this.trace = menu_trace;
    }

    public Menu(Integer gmnu_code, String menu_lib, Integer menu_ordre, Integer menu_visible, Integer menu_deleted, Integer menu_bouton, Integer menu_parent, String menu_controlleur, String menu_navigation, Integer menu_flag_trace, String menu_trace, Set<Role> roles) {
        super();
        this.groupeMenu = gmnu_code;
        this.lib = menu_lib;
        this.ordre = menu_ordre;
        this.visible = menu_visible;
        this.deleted = menu_deleted;
        this.bouton = menu_bouton;
        this.parent = menu_parent;
        this.controlleur = menu_controlleur;
        this.navigation = menu_navigation;
        this.flag_trace = menu_flag_trace;
        this.trace = menu_trace;
        this.roles = roles;
    }

    public int getId() {
        return id;
    }

    public void setId(int menu_id) {
        this.id = menu_id;
    }

    public Integer getGroupeMenu() {
        return groupeMenu;
    }

    public void setGroupeMenu(Integer gmnu_code) {
        this.groupeMenu = gmnu_code;
    }

    public String getLib() {
        if (this.env != null)
            return env.getProperty(lib.trim());
        return lib;
    }

    public void setLib(String menu_lib) {
        this.lib = menu_lib;
    }

    public Integer getOrdre() {
        return ordre;
    }

    public void setOrdre(Integer menu_ordre) {
        this.ordre = menu_ordre;
    }

    public Integer getVisible() {
        return visible;
    }

    public void setVisible(Integer menu_visible) {
        this.visible = menu_visible;
    }

    public Integer getDeleted() {
        return deleted;
    }

    public void setDeleted(Integer menu_deleted) {
        this.deleted = menu_deleted;
    }

    public Integer getBouton() {
        return bouton;
    }

    public void setBouton(Integer menu_bouton) {
        this.bouton = menu_bouton;
    }

    public Integer getParent() {
        return parent;
    }

    public void setParent(Integer menu_parent) {
        this.parent = menu_parent;
    }

    public String getControlleur() {
        return controlleur;
    }

    public void setControlleur(String menu_controlleur) {
        this.controlleur = menu_controlleur;
    }

    public String getNavigation() {
        try {
            if (this.env != null) 
                return env.getProperty(navigation.trim());
            return navigation.trim();
        } catch (NullPointerException npe) {
            return " --- ";
        }
    }

    public void setNavigation(String menu_navigation) {
        this.navigation = menu_navigation;
    }

    public String getTrace() {
        if (this.env != null)
            return HtmlUtils.htmlUnescape(env.getProperty(trace));
        return trace;
    }

    public void setTrace(String menu_trace) {
        this.trace = HtmlUtils.htmlUnescape(menu_trace);
    }

    public Integer getFlag_trace() {
        return flag_trace;
    }

    public void setFlag_trace(Integer menu_flag_trace) {
        this.flag_trace = menu_flag_trace;
    }

    public Set<Role> getRoles() {
        return roles;
    }

    public void setRoles(Set<Role> roles) {
        this.roles = roles;
    }

    public void setEnv(Environment env) {
        this.env = env;
    }

    public int getDepth() {
        return depth;
    }

    public void setDepth(int depth) {
        this.depth = depth;
    }

    public boolean isAffectedToARole() {
        return affectedToARole;
    }

    public void setAffectedToARole(boolean affectedToARole) {
        this.affectedToARole = affectedToARole;
    }

    @Override
    public boolean equals(Object obj) { // pour pouvoir utiliser la méthode "contains" sur une liste de Menu

        if (this == null && obj == null)
            return true;

        if (this != null && obj != null && obj instanceof Menu)
            return id == ((Menu)obj).getId();

        return super.equals(obj);

    }

}

I want to test if a Set of Menu's contains a particular Menu :

Set<Menu> affected_menus = roleDao.getListMenu(role_code); // gets all menus affected to a role_code

for (Menu menu : temp) {
    if (!affected_menus.isEmpty() && affected_menus.contains(menu))
        menu.setAffectedToARole(true);
    else
        menu.setAffectedToARole(false);
}

At runtime all code goes to menu.setAffectedToARole(false);

So what is wrong ?

Paulo Mattos
  • 18,845
  • 10
  • 77
  • 85
pheromix
  • 18,213
  • 29
  • 88
  • 158
  • Like @vitaliy-moskalyuk sayed, you must override `hashCode();`, `Set>.contains(Object o);` use hashCode(). – Zorglube Jun 06 '17 at 14:23
  • Two side notes, @pheromix. You don't need to put `super()` (no arguments) in a constructor. Your `equals` implementation is wrong. `this == null` cannot possibly be true! And it should never call `super.equals`. The semantics of the superclass implementation will not match. – Lew Bloch Jun 06 '17 at 14:31

3 Answers3

2

The javadoc of the the int hashCode() method from the Object class explains that :

it returns a hash code value for the object. This method is supported for the benefit of hash tables such as those provided by java.util.HashMap.

The hashCode() method intention is clear : being using in collections relying on hash tables : HashMap, HashSet, LinkedHashMap, etc…

Besides, the general contract of hashcode() mentions the relation between equals() and hashcode() :

If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result.

So to be able to use your custom class with a HashSet, you need to override both equals() and hashcode() in a consistent way.

davidxxx
  • 125,838
  • 23
  • 214
  • 215
2

When overriding equals you must always override hashCode as well. Both methods are used together across Java Collections, etc.

In your case, this implementation might be enough:

@Override
public int hashCode() {
    return id;
}

Also, your equals implementation could use some help as well:

@Override
public boolean equals(Object obj) {
    if (obj instanceof Menu)
        return id == ((Menu)obj).getId();
    return false;
 }
Paulo Mattos
  • 18,845
  • 10
  • 77
  • 85
1

you should also override hashCode() method

here some info: Why do I need to override the equals and hashCode methods in Java?

Vitaliy Moskalyuk
  • 2,463
  • 13
  • 15