@GeneratedValue和@GenericGenerator的区别

2022-08-31 16:23:14

有时我发现他们在一起,有时是孤独的...其他时候,他们似乎也这样做。

有什么区别?

下面是三个示例。他们有什么不同之处?为什么我不能只使用@GeneratedValue来表示所有这些?

示例 1

@Id
@GeneratedValue(generator="increment")
@GenericGenerator(name="increment", strategy = "increment") 
Long id;

示例 2

@Id @GeneratedValue(strategy=GenerationType.SEQUENCE)
private int userId;

示例 3

@ElementCollection
@JoinTable(name="Address",
   joinColumns=@JoinColumn(name="user_id")
)
@GenericGenerator(name="hilo-gen", strategy="hilo")
@CollectionId(columns = @Column(name="Address_id"), generator = "hilo-gen", type = @Type(type="long"))
Collection<Addr> listOfAddresses = new ArrayList<Addr>();

答案 1

使用 ORM 时,通常需要生成主键值。

批注表示将生成列的值,该值必须使用 该值进行批注。元素和注释上描述了如何获得生成的值。@GeneratedValue@Idstrategygenerator

注释上的元素有四个可能的值:、 和 。查看更多strategy@GeneratedValueIDENTITYAUTOTABLESEQUENCE

因此,为了回答问题的第 2 部分,代码片段指示 的值将通过数据库中的序列获得。userId

注释的元素表示主密钥生成器的名称。在问题的第 1 部分中,代码段指示将使用 named 键值来获取主键值。 然后在下一个注释中定义。 是一个休眠注释,用于表示自定义生成器,它可以是 Hibernate 提供的生成器的类或快捷方式。 是休眠生成器的快捷方式,它:generator@GeneratedValuegeneratorincrementincrement@GenericGenerator@GenericGeneratorincrement

生成 long、short 或 int 类型的标识符,这些标识符仅在没有其他进程将数据插入同一表中时才是唯一的。不要在群集中使用。

在问题的第三部分中,代码使用了一个休眠生成器,该生成器:hilo

使用 hi/lo 算法有效地生成 long、short 或 int 类型的标识符,给定表和列(默认情况下分别hibernate_unique_key和next_hi)作为 hi 值的源。hi/lo 算法生成仅对特定数据库唯一的标识符。


答案 2

为了扩展@kevin-bowersox的答案。
休眠主键生成策略与特定生成器之间的关系,如org.hibernate.id.IdentifierGeneratorFactory

static {
    GENERATORS.put("uuid", UUIDHexGenerator.class);     // "deprecated" for new use
    GENERATORS.put("hilo", TableHiLoGenerator.class);   // removed in Hibernate 5
    GENERATORS.put("assigned", Assigned.class);
    GENERATORS.put("identity", IdentityGenerator.class);
    GENERATORS.put("select", SelectGenerator.class);
    GENERATORS.put("sequence", SequenceGenerator.class);
    GENERATORS.put("seqhilo", SequenceHiLoGenerator.class);
    GENERATORS.put("increment", IncrementGenerator.class);
    GENERATORS.put("foreign", ForeignGenerator.class);
    GENERATORS.put("guid", GUIDGenerator.class);
    GENERATORS.put("uuid.hex", UUIDHexGenerator.class); // uuid.hex is deprecated
    GENERATORS.put("sequence-identity", SequenceIdentityGenerator.class);
}

在Hibernate 4.3中,我发现类有3个以上的策略:org.hibernate.id.factory.internal.DefaultIdentifierGeneratorFactory

    register("uuid2", UUIDGenerator.class);
    register("enhanced-sequence", SequenceStyleGenerator.class);
    register("enhanced-table", TableGenerator.class);

上述 15 种策略以及 是默认情况下在 Hibernate 中支持的 16 代策略。native

示例:native

@GeneratedValue(generator = "nativeGenerator")
@GenericGenerator(name = "nativeGenerator", strategy = "native")

推荐