应该如何在Hibernate中实现模型类的equals和hashcode?常见的陷阱是什么?对于大多数情况,默认实现是否足够好?使用商业密钥有什么意义吗?
在我看来,当考虑到懒惰的提取,id生成,代理等时,很难在任何情况下都能正常工作.
我想检查实体是否在另一个实体的Collection成员(@OneToMany或@ManyToMany)中:
if (entity2.getEntities1().contains(entity1)) { }
Run Code Online (Sandbox Code Playgroud) 为什么StringBuffer的/ StringBuilder的没有覆盖equals(),hashcode()从对象的方法?
请建议我清楚的图片,以帮助理解问题...
一些类由框架填充(如bean).因此,您无法保证所有字段都已设置.
示例:标记为@Entity通常具有Integer id字段的类.hashCode可以写成:
public int hashCode() {
return id.hashCode();
}
Run Code Online (Sandbox Code Playgroud)
但是defencive代码可能看起来像:
public int hashCode() {
return (id != null) ? id.hashCode() : 0;
}
Run Code Online (Sandbox Code Playgroud)
我是否需要使用try { ... } catch (Exception e)in hashCode和equals函数对null或环绕码进行写检查?
我没有关于defencive编码的论据就是这种情况,因为它隐藏了将不一致的对象隐藏到集合中并导致延迟错误.我错了吗?
更新我写了这样的代码:
import java.util.*;
class ExceptionInHashcode {
String name;
ExceptionInHashcode() { }
ExceptionInHashcode(String name) { this.name = name; }
public int hashCode() {
// throw new IllegalStateException("xxx");
return this.name.hashCode();
}
public static void main(String args[]) { …Run Code Online (Sandbox Code Playgroud) 几天后我正在使用Junit的Matchers功能.一切正常,但我正在寻找一个使用比较器进行比较的匹配器,它不依赖于对象等于方法.
我想替换
Assert.assertThat(one, CoreMatchers.equalTo(two)
Run Code Online (Sandbox Code Playgroud)
与(伪代码)类似的东西
Assert.assertThat(eins, CoreMatchers.equalTo(operand, new MyComparator())
Run Code Online (Sandbox Code Playgroud)
你知道是否有一个简单的开箱即用的解决方案?我没有在谷歌找到一个,也不想写一个.
我对JPA和Hibernate都很陌生(虽然我正在努力学习!)我正在努力解决一个我似乎无法找到一个简单解决方案的问题,所以现在就是这样.
我有一个看起来像下面这样的实体:
@Entity
@Table(name = "mytable1")
public class EntityOne {
// surrogate key, database generated
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
// business key
@Column(name = "identifier", nullable = false, unique = true)
private String identifier;
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.REFRESH)
@JoinColumn(name = "twoId", nullable = false)
private EntityTwo two;
@OneToMany(mappedBy = "entityOne", fetch = FetchType.EAGER,
cascade = {CascadeType.ALL}, orphanRemoval = true)
private Set<EntityThree> resources = new HashSet<>();
// getters/setters omitted
@Override
public int hashCode() …Run Code Online (Sandbox Code Playgroud) MyEntity 是一个带有生成 id 的经典 JPA 实体。我想根据 id 自动将字段 (myStringField) 设置为值。在此示例中,如果 id 为 43,则我\xe2\x80\x99d 喜欢将其设置为 \xe2\x80\x9cfoo43\xe2\x80\x9d。
\n\n由于 id 是由数据库自动生成的,因此在 em.persist(myEntity) 调用之前它为 null。但是在持久化之后,它有一个由Hibernate分配的id(在DB序列上调用NEXTVAL)。所以,我想声明一个 @PostPersist 方法,如下所示:
\n\npackage ...;\n\nimport javax.persistence.Entity;\nimport javax.persistence.GeneratedValue;\nimport javax.persistence.GenerationType;\nimport javax.persistence.Id;\nimport javax.persistence.PostPersist;\n\n\n@Entity\npublic class MyEntity {\n\n @Id @GeneratedValue(strategy = GenerationType.AUTO)\n private Long id;\n\n private String myStringField;\n\n @PostPersist\n public void postPersist(){\n System.out.println("The id = " + id);\n this.myStringField = "foo" + id;\n }\n\n public String getMyStringField() {\n return myStringField;\n }\n ...\n}\nRun Code Online (Sandbox Code Playgroud)\n\n下面是一些创建和持久化实体的代码:
\n\npackage ...;\n\nimport javax.persistence.EntityManager;\nimport javax.persistence.PersistenceContext;\n\nimport org.springframework.stereotype.Service;\nimport org.springframework.transaction.annotation.Transactional;\n\n@Transactional\n@Service\npublic class MySpringBean …Run Code Online (Sandbox Code Playgroud) 我有一个BaseEntity类,它是我的应用程序中所有JPA实体的超类.
@MappedSuperclass
public abstract class BaseEntity implements Serializable {
private static final long serialVersionUID = -3307436748176180347L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID", nullable=false, updatable=false)
protected long id;
@Version
@Column(name="VERSION", nullable=false, updatable=false, unique=false)
protected long version;
}
Run Code Online (Sandbox Code Playgroud)
每个JPA实体都延伸BaseEntity并继承id和version属性BaseEntity.
这里实施equals()和hashCode()方法的最佳方法是BaseEntity什么?BaseEntity将继承equals()和hashCode()行为形式的每个子类BaseEntity.
我想做这样的事情:
public boolean equals(Object other){
if (other instanceof this.getClass()){ //this.getClass() gives class object but instanceof operator expect …Run Code Online (Sandbox Code Playgroud) 假设我有以下情况:
@Entity
public class Person {
@Id
private Long id; //Surrogate key
@Embedded
private Name name; //Natural key
public int hashCode() {
... //based on natural key Name
}
public boolean equals(Object obj) {
... //based on natural key Name
}
}
@Embeddable
public class Name {
private String firstName;
private String middleName;
private String lastName;
//Should I implement equals/hashCode baseed on the three fields?
}
Run Code Online (Sandbox Code Playgroud)
Name类是否应该在Name类上实现equals和hashCode以使Person等于正常工作?
对于将用作EmbeddedId的Embeddable对象是必须的.但在这个例子中我使用的是代理键.
我正在阅读Eric Evans关于DDD的书,我对以下引用有疑问.equals()如果不使用属性,如何制作方法?我正在使用JPA,并且我有一个唯一的id属性,但在实际持久保存实体之前不会设置.所以你会怎么做?我已经基于属性实现了equals方法,我理解为什么你不应该因为它在我的项目中失败了.
关于实体的部分:
当一个对象通过其标识而不是其属性进行区分时,将该主要对象定义为模型中的定义.保持课堂定义简单,重点关注生命周期的连续性和身份.定义区分每个对象的方法,无论其形式或历史如何.警告要求按属性匹配对象的要求.定义一个保证为每个对象生成唯一结果的操作,可以通过附加保证唯一的符号.这种识别方法可能来自外部,也可能是由系统创建的任意标识符,但它必须与模型中的标识区别相对应.模型必须定义相同的东西意味着什么.
http://www.amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215