我正在使用Spring Framework 4& Hibernate 4。
我将@Future约束添加到我的实体中,之后我遇到了Exception:
javax.validation.ValidationException: HV000041: Call to TraversableResolver.isReachable() threw an exception.
经过一些研究后我发现它是由hashCode方法中包含id
引起的,如果我从hashCode方法中删除id
,那么Exception就会消失并且按预期工作。
@Override
public int hashCode() {
int result = id.hashCode();
// Code intentionally omitted
return result;
}
问题:为什么我不能像id
这样的hashCode
方法使用@Entity
@Table(name = "ACTIVITY")
public class ActivityEntity implements Serializable {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID", nullable = false, length = 10)
private Long id;
@Temporal(TemporalType.TIMESTAMP)
@Future
@Column(name = "ACTIVITY_FROM", nullable = false, length = 19)
private Date activityFrom;
// Code of other attributes intentionally omitted
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Date getActivityFrom() {
return activityFrom;
}
public void setActivityFrom(Date activityFrom) {
this.activityFrom = activityFrom;
}
// Code of other methods intentionally omitted
@Override
public int hashCode() {
int result = id.hashCode();
// Code intentionally omitted
return result;
}
}
?我该怎么改变它?
实体代码:
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID", length = 10)
private Long id;
解决方案:
我更改了属性ID:
int result = id != null ? id.hashCode() : 0;
我更改了hashCode方法:
{{1}}
答案 0 :(得分:0)
首先:您发布的堆栈跟踪是不够的,因为它隐藏了异常的根本原因。但无论如何,我怀疑是空指针;)
您的代码有两个问题。第一个问题是您始终假设一个非null的id,如果没有持久化的新实体,则(很可能)不是真的。因此,通过在哈希码方法中检查null来解决此问题。
Eclipse可以帮助您生成equals / hashcode方法,这些方法与我通常需要编码的方法很接近。
第二个问题不是那么明显。当您使用hibernate时,如果此实体是延迟加载的,则任何实体实例都可能是代理。作为副作用,代理(作为子类实现)也包含这些属性,您可能无法获取所期望的属性。据我所知,直接截取字段并未实现。
所以要解决第二个问题,你真的必须使用"非最终版!" hashcode / equals中的getter方法,由代理拦截并委托给您的实体实例。