1

我是 Hibernate、Spring、JPA 框架的初学者。目前,我正在尝试使用 Spring 3.1.1 - JPA with Hibernate 4 Implementation 创建一个简单的架构。

目前,为了不依赖于我的数据库,我使用 TableGenerator 创建了一些 id:

@Id
@Column(name = "AIR_ID", unique = true, nullable = false)
@TableGenerator(name="aircraftSeqStore", 
    table="T_S_APP_SEQ_STORE_AST", 
    pkColumnName="AST_SEQ_NAME",
    valueColumnName = "AST_SEQ_VALUE",
    pkColumnValue = "T_R_AIRCRAFT_AIR.AIR_ID", 
    allocationSize=1)
@GeneratedValue(strategy=GenerationType.TABLE, 
    generator="aircraftSeqStore")       
private Integer id;

经过我的研究,并阅读了“不要让休眠窃取你的身份”文章之后,我真的不明白如何管理我的身份。

我是否应该修改我的实体以用分配的值替换它们(如何在 JPA 中做到这一点?)我是否应该生成一个 UUID 以在创建瞬态对象时直接影响 id?

在许多表中,我有一些简单的数据(id、name)。我以为我可以管理唯一的名称属性上的哈希码和 equals 方法,但在创建对象时也不受影响....(所以我认为相同的 pb 与 id 为空?)。

有关信息,我有一个表示多连接表的实体(此连接表中的 3 个 FK)。

那么你对我有什么建议呢?为性能生成 UUID 还不错吗?


编辑 :

这个实体可行吗?

@Id
@Column(name = "AIR_ID", unique = true, nullable = false)
@TableGenerator(name="aircraftSeqStore", 
    table="T_S_APP_SEQ_STORE_AST", 
    pkColumnName="AST_SEQ_NAME",
    valueColumnName = "AST_SEQ_VALUE",
    pkColumnValue = "T_R_AIRCRAFT_AIR.AIR_ID", 
    allocationSize=1)
@GeneratedValue(strategy=GenerationType.TABLE, 
    generator="aircraftSeqStore")       
private Integer id;

@Column(name = "AIR_BUSINESS_ID", unique = true, nullable = false)
private String uuid = IdGenerator.createId();

public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || !(o instanceof Aircraft))
        return false;

    Aircraft other = (Aircraft)o;

    if (uuid == null) return false;
    return uuid .equals(other.getUuid ());
}

public int hashCode() {
    if (uuid  != null) {
        return uuid .hashCode();
    } else {
        return super.hashCode();
    }
}

谢谢你。

4

3 回答 3

3

与每个问题一样,完整但很少有用的答案是:视情况而定。

更有用的变体是:

我大部分时间都使用 GenerationType.Auto,并且不实现 equals 和 hashcode。

结果是:

  • 只要实体对象存在于同一个会话中,您就可以很好地比较它们,因为休眠将确保每个数据库行由每个会话的单个实例表示。

  • equals 和 hashcode 随着时间的推移是稳定的,所以你可以把你的对象放在 HashSets 中,改变对象,仍然可以再次取出它们。

  • 如果你想处理来自不同会话的对象,你必须显式地比较 ids 或 ids + hashcode 或一些业务密钥,可能通过实现一个 Comparator。在决定使用什么和实现它时付出的额外努力会提醒你,你实际上正在做一些违背 Hibernate 的事情。

关于性能:取决于数据库和用例 UUID 可能具有成本性能,因为它们相当大,或者提高性能,因为它们可以在客户端上创建,从而节省数据库往返。大多数情况下,应用程序中的其他故障(尤其是在使用 Hibernate 时)比 ID 生成的任何影响都要大得多。

于 2012-08-10T10:32:04.147 回答
0

我最近问了一个问题,探索了通常模式的替代方案:这种 JPA“缓存 hashCode”模式有什么问题吗?

我包含了一个我通常使用@Entity类的示例 - 在构造时生成UUIDs。碰撞的可能性UUID是如此之小,以至于你最好担心宇宙射线。有些人不喜欢UUIDs,因为他们觉得有性能损失。我没有看到性能与 相比有任何变化Integer,但我认为发生碰撞的可能性Integer很小,足以引起关注。

@Id
private UUID id = UUID.randomUUID();

@Override
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (!(obj instanceof MY_CLASS) || id == null)
        return false;
    MY_CLASS other = (MY_CLASS) obj;
    return id.equals(other.id);
}

@Override
public int hashCode() {
    Preconditions.checkNotNull(id, "id must be set before @Entity.hashCode can be called");
    return id.hashCode();
}

有时我想检查实际数据本身是否匹配,在这种情况下,我创建一个这样的方法:

public boolean hasSameProperties(Note other) {
    Preconditions.checkNotNull(other);
    if (this == other)
        return true;
    return Objects.equal(source, other.source)
            && Objects.equal(title, other.title)
            && Objects.equal(tags, other.tags)
            && Objects.equal(contents, other.contents);
}
于 2012-08-10T10:48:33.360 回答
0

通常我使用:

    @Id
@GeneratedValue(strategy=GenerationType.AUTO)     
    private Integer id

并让持久性提供者选择正确的。希望这对你有帮助

于 2012-08-10T10:21:41.027 回答