Lombok 是一个非常受欢迎和有用的图书馆。尽管如此,请注意Lombok @EqualsAndHashCode对实体的影响可能会带来严重问题。
实体应实施equals()和hashCode()。主要问题是Hibernate要求实体在其所有状态转换(瞬态,附加,分离 和删除)中等于自身。使用Lombok @EqualsAndHashCode不会尊重此要求。
避免下面这些方法:
1. 避免使用的Lombok默认行为@EqualsAndHashCode:
@Entity @EqualsAndHashCode public class LombokDefaultProduct implements Serializable {
private static final long serialVersionUID = 1L;
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id;
private String name; private String code;
|
2. 避免使用只有主键的Lombok@EqualsAndHashCode
@Entity @EqualsAndHashCode(exclude = {"name", "code"}) public class LombokIdProduct implements Serializable {
private static final long serialVersionUID = 1L;
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id;
private String name; private String code;
|
3. 避免使用默认equals()和hashCode(),下面实体没有编写自己的这两个方法,使用的是默认,不推荐这样做:
@Entity public class DefaultProduct implements Serializable {
private static final long serialVersionUID = 1L;
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id;
private String name; private String code;
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getCode() { return code; }
public void setCode(String code) { this.code = code; }
}
|
4. 避免使用只依赖主键的equals()和hashCode():@Entity public class IdProduct implements Serializable {
private static final long serialVersionUID = 1L;
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id;
private String name; private String code;
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getCode() { return code; }
public void setCode(String code) { this.code = code; }
@Override public int hashCode() { int hash = 3; hash = 89 * hash + Objects.hashCode(this.id); return hash; }
@Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final IdProduct other = (IdProduct) obj; if (!Objects.equals(this.id, other.id)) { return false; } return true; } }
|
推荐这些方法:1. 依靠@NaturalId
@Entity public class NaturalIdProduct implements Serializable {
private static final long serialVersionUID = 1L;
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id;
private String name;
@NaturalId @Column(nullable = false, updatable = false, unique = true, length = 50) private String code;
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getCode() { return code; }
public void setCode(String code) { this.code = code; }
@Override public boolean equals(Object o) { if (this == o) { return true; } if (!(o instanceof NaturalIdProduct)) { return false; } NaturalIdProduct naturalIdProduct = (NaturalIdProduct) o; return Objects.equals(getCode(), naturalIdProduct.getCode()); }
@Override public int hashCode() { return Objects.hash(getCode()); }
}
|
2. 依靠主键:@Entity public class GoodProduct implements Serializable {
private static final long serialVersionUID = 1L;
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id;
private String name; private String code;
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getCode() { return code; }
public void setCode(String code) { this.code = code; }
@Override public boolean equals(Object obj) { if (this == obj) { return true; } if (!(obj instanceof GoodProduct)) { return false; } return id != null && id.equals(((GoodProduct) obj).id); }
@Override public int hashCode() { return 2018; }
}
|
良好的equals()和hashCode():
源代码可以在这里找到