@GeneratedValue和@GenericGenerator之间的区别

use*_*212 47 java orm hibernate

有时候我会把它们放在一起,有时候只有它们......有时候它们似乎也是这样.

有什么不同?

这是三个例子.他们有什么不同的做法?为什么我不能只为所有这些使用@GeneratedValue?

例1

@Id
@GeneratedValue(generator="increment")
@GenericGenerator(name="increment", strategy = "increment") 
Long id;
Run Code Online (Sandbox Code Playgroud)

例2

@Id @GeneratedValue(strategy=GenerationType.SEQUENCE)
private int userId;
Run Code Online (Sandbox Code Playgroud)

例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>();
Run Code Online (Sandbox Code Playgroud)

Kev*_*sox 73

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

@GeneratedValue注释表示一个列中的值,必须以进行注释@Id被生成.元素strategygenerator注释描述了如何获得生成的值.

有四个可能的值strategy的元素@GeneratedValue注释:IDENTITY,AUTO,TABLESEQUENCE. 查看更多.

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

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

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

在您的问题的第三部分中,代码使用hiloHibernate生成器:

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


Moh*_*han 10

@Entity
@Table(name="Honey")
public class Honey implements Serializable{
    private static final long serialVersionUID = 42L;
    @Id
    //@SequenceGenerator(name="honeySequence",sequenceName="HONEY_SEQ")
    @org.hibernate.annotations.GenericGenerator(name="honeySequence", strategy = "sequence", 
    parameters = { 
            @Parameter(name="sequence", value="HONEY_SEQ") } 
    )
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="honeySequence")
    private int Id;
    private String name;
    private String taste;
Run Code Online (Sandbox Code Playgroud)
  • @GeneratedValue 仅用于获取生成的值。两个参数strategygenerator用于定义如何获取值。
  • @GenericGenerator 用于将用户定义的序列生成器映射到您的休眠会话。
  • 您还可以使用我在代码中注释的 @SequenceGenerator。这不是一个简单的序列生成器,而是一个适用于HILO算法的生成器。因此,您会发现序列中有很多差距,例如您的第一个值将从 50 开始,因为默认分配大小为 50。

因此,最好将 @GenericGenerator 用于您自己的架构。但是,如果您必须使用 @SequenceGenerator,则必须手动编辑序列以拥有另外两个属性allocationSize=1initialValue=1。要使用这些属性,您需要在hibernate.cfg.xml文件中添加 apropert

<property name="hibernate.id.new_generator_mappings">true</property>
Run Code Online (Sandbox Code Playgroud)


naX*_*aXa 8

延长@ kevin-bowersox的答案.
Hibernate主键生成策略和特定生成器之间的关系,分别如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);
}
Run Code Online (Sandbox Code Playgroud)

在Hibernate 4.3中,我发现org.hibernate.id.factory.internal.DefaultIdentifierGeneratorFactory了另外3个策略:

    register("uuid2", UUIDGenerator.class);
    register("enhanced-sequence", SequenceStyleGenerator.class);
    register("enhanced-table", TableGenerator.class);
Run Code Online (Sandbox Code Playgroud)

以上十五种策略,native默认情况下是Hibernate支持的十六代策略.

示例native:

@GeneratedValue(generator = "nativeGenerator")
@GenericGenerator(name = "nativeGenerator", strategy = "native") 
Run Code Online (Sandbox Code Playgroud)