JPA2实体中的奇怪行为

时间:2013-02-20 12:54:56

标签: jpa-2.0 java-ee-6 ejb-3.1

在观察一些日志条目时,我观察到了一种行为,我不明白。 我重新创建了这个场景。

实体:

@Entity
public class SimpleEntity implements Serializable {

    private static final long serialVersionUID = 2777681889998131084L;

    @Id
    @GeneratedValue
    private Long id;
    @Version
    private Long version;
    @Column(length = 20, nullable = false, unique = true, updatable = false)
    @NotNull
    private String username;
    @Column(length = 60)
    private String email;

    // Constructors

    // getters/setters

    // @Override
    // toString : generated by eclipse, modified to include super.toString
    // hashCode, equals : generated by eclipse, based on 'username'

}

测试用例

@Test
public void testUpdate() {
    SimpleEntity simple;
    SimpleEntity simple2;

    try {
        simple = bean.create(new SimpleEntity("user",
                "original@original.com"));  // em.persist
        simple.setEmail("updated@updated.com");
        simple2 = bean.update(simple);          // em.merge
        System.out.println(simple);
        System.out.println(simple2);
    } catch (EJBException e) {
        System.out.println(e.getMessage());
    }
}

打印与上述System.out.println行相对应的以下行

...SimpleEntity@36ebea SimpleEntity [id=1, version=1, username=user, email=updated@updated.com]
...SimpleEntity@36ebea SimpleEntity [id=1, version=2, username=user, email=updated@updated.com]

我觉得奇怪的是两个实体的地址相同( SimpleEntity @ 36ebea ),但如果我查看数据,则不一样。 '版本'是不同的。 ( 1 & 2

同一个实例(地址是否相同)如何显示不同的数据?是否有一些代理?如何?

1 个答案:

答案 0 :(得分:1)

simplesimple2实际上是两个不同的实例。你说“toString:由eclipse生成,修改为包含super.toString”。来自toString()的继承Object如下所示:

public String toString() {
    return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

所以@36ebea不是对象的地址,但是它的哈希码(仅基于username)对于只有version不同的不同实例保持不变。

您可能希望使用System.identityHashCode()来获取从对象的地址派生的哈希码(如果您没有覆盖从{{1继承的那个),它基本上会重新调用您从调用hashCode()获得的内容}})。