将@Future注释添加到实体后 - TraversableResolver.isReachable()引发了异常

时间:2014-04-25 22:36:48

标签: java spring entity-framework hibernate validation

我正在使用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}}

1 个答案:

答案 0 :(得分:0)

首先:您发布的堆栈跟踪是不够的,因为它隐藏了异常的根本原因。但无论如何,我怀疑是空指针;)

您的代码有两个问题。第一个问题是您始终假设一个非null的id,如果没有持久化的新实体,则(很可能)不是真的。因此,通过在哈希码方法中检查null来解决此问题。

Eclipse可以帮助您生成equals / hashcode方法,这些方法与我通常需要编码的方法很接近。

第二个问题不是那么明显。当您使用hibernate时,如果此实体是延迟加载的,则任何实体实例都可能是代理。作为副作用,代理(作为子类实现)也包含这些属性,您可能无法获取所期望的属性。据我所知,直接截取字段并未实现。

所以要解决第二个问题,你真的必须使用"非最终版!" hashcode / equals中的getter方法,由代理拦截并委托给您的实体实例。