简体   繁体   English

Hibernate:使用复合键的对象和实体身份映射的策略/模式?

[英]Hibernate: Strategy/pattern for object and entity identity mapping using composite keys?

What is a general collision-free Java best practice to generate hash codes for any-type (atomic types) multi-column primary keys? 什么是生成任何类型(原子类型)多列主键哈希码的通用无冲突Java最佳实践?

I thought about it for a few hours and came to the conclusion, that a string concatenated by all primary key columns would be the only reliable way to do so. 我考虑了好几个小时后得出结论,由所有主键列连接的字符串是这样做的唯一可靠方法。 Then calling Java's hashCode method on that concatenated string should yield a unique integer. 然后,在该串联字符串上调用Java的hashCode方法应产生一个唯一的整数。 (it would in fact somehow mimic what a database index does, not sure here though) (实际上,它会以某种方式模仿数据库索引的作用,尽管此处不确定)

For a multi-column primary key of the form 对于表单的多列主键

CREATE TABLE PlayerStats
(
    game_id INTEGER,
    is_home BOOLEAN,
    player_id SMALLINT,
    roster_id SMALLINT,
    ... -- (game_id, is_home) FK to score, (player_id, roster_id) FK to team member
    PRIMARY KEY (game_id, is_home, player_id, roster_id)
)

a hash code could be calculated like: 哈希码的计算方式如下:

@Override
public int hashCode()
{
    //                                                                 maxchars:
    String surrogate =   String.format("%011d", this.gameId)         //11
                       + String.format("%01d" , this.isHome ? 1 : 0) //1
                       + String.format("%011d", this.playerId)       //6
                       + String.format("%011d", this.rosterId)       //6

    System.out.println("surrogate = '" + surrogate + "'");

    return surrogate.hashCode();
}

Of course, this only works with HashSets and Hashtable when equals is also based on this. 当然,当equals也基于此时,这仅适用于HashSets和Hashtable。

My question: is this a good general strategy? 我的问题:这是一个好的总体策略吗?

I can see on-the-fly calculation might not be the fastest. 我可以看到即时计算可能不是最快的。 You might want to recalculate the hash code whenever a composite key value was changed (eg call a rehash() method from within every setter operating on a key property. 每当更改组合键值时,您可能希望重新计算哈希码(例如,从对键属性进行操作的每个setter内调用rehash()方法。

Suggestions and improvements welcome. 欢迎提出建议和改进。 Aren't there any generally known strategies for this? 没有任何众所周知的策略吗? A pattern? 一种模式?

The hash code is used as an index to look up elements in the data set that have the same code. 哈希码用作索引,以查找数据集中具有相同代码的元素。 The equals method is then used to find matches within the set of elements that have the same hash code. 然后使用equals方法在具有相同哈希码的元素集中查找匹配项。 As such, the generated hash code doesn't have to be 100% unique. 这样,生成的哈希码不必是100%唯一的。 It just needs to be "unique enough" to create a decent distribution among the data elements so that there isn't a need to invoke the equals method on a large number of items with the same hashCode value. 它只需要“足够独特”即可在数据元素之间创建适当的分布,从而无需在具有相同hashCode值的大量项目上调用equals方法。

From that perspective, generating lots and lots of strings and computing hash codes on those strings seems like an expensive way to avoid an equals operation that consists of 3 integer and 1 boolean comparison. 从这个角度来看,生成大量字符串并在这些字符串上计算哈希码似乎是避免由3个整数和1个布尔比较组成的equals操作的昂贵方法。 It also doesn't necessarily guarantee uniqueness in the hash code value. 它也不一定保证哈希码值的唯一性。

My recommendation would be to start with a simple approach of having the hash code of the key being the sum of the hash codes of its constituents. 我的建议是从一种简单的方法开始,即将密钥的哈希码作为其组成部分的哈希码之和。 If that doesn't provide a good distribution because all of the ids are in a similar range, you could try multiplying the ids by some different factors before summing. 如果由于所有ID都在相似范围内而不能提供良好的分布,则可以在累加之前尝试将ID乘以一些不同的因子。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何使用1个PK来使用复合键一对多地进行Hibernate XML映射 - How to do Hibernate XML-Mapping, for one-to-many using 1 PK to map to another Entity with Composite Keys 带有复合键的Hibernate @ManyToMany映射 - Hibernate @ManyToMany mapping with composite keys Hibernate:映射@OneToMany / @ManyToOne问题(不使用实体主键) - Hibernate: mapping @OneToMany / @ManyToOne problems (not using entity primary keys) JPA Hibernate-将MySQL复合键映射到JPA(Hibernate)实体 - JPA Hibernate - Mapping MySQL Composite keys to JPA (Hibernate) entities 使用 DataJpaTest 时在 Hibernate 上使用 IdClass 的复合键作为复合键 - Composite keys using IdClass on Hibernate for composite keys when using DataJpaTest 使用主复合键中的一列将多对一映射休眠 - Hibernate many to one mapping using one column which is in primary composite keys 将 JSON 对象映射到 Hibernate 实体 - Mapping JSON object to Hibernate entity Hibernate:使用另一个实体中引用的复合键来面对“id的断列映射” - Hibernate: Facing “broken column mapping for id” using composite key referenced in another entity 使用休眠的未映射复合对象 - Unmapped composite object using hibernate 如何使用注释表示 Hibernate 中的复合键? - How to Represent Composite keys in Hibernate using Annotations?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM