Java @GeneratedValue 和 @GenericGenerator 的区别
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18205574/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Difference between @GeneratedValue and @GenericGenerator
提问by user1883212
Sometimes I find them together, sometimes alone... other times they seem to do the same.
有时我发现他们在一起,有时单独……有时他们似乎也做同样的事情。
What's the difference?
有什么不同?
Here are three examples. What do they do of different? Why can't I use just @GeneratedValue for all of them?
下面是三个例子。他们有什么不同?为什么我不能对所有这些只使用 @GeneratedValue?
Example 1
示例 1
@Id
@GeneratedValue(generator="increment")
@GenericGenerator(name="increment", strategy = "increment")
Long id;
Example 2
示例 2
@Id @GeneratedValue(strategy=GenerationType.SEQUENCE)
private int userId;
Example 3
示例 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>();
回答by Kevin Bowersox
When using an ORMit is often necessary to generate a primary key value.
使用ORM 时,通常需要生成主键值。
The @GeneratedValue
annotation denotes that a value for a column, which must be annotated with @Id
is generated. The elements strategy
and generator
on the annotation describe how the generated value is obtained.
的@GeneratedValue
注释表示一个列中的值,必须以进行注释@Id
被生成。注释上的元素strategy
和generator
描述了如何获得生成的值。
There are four possible values for the strategy
element on the @GeneratedValue
annotation: IDENTITY
, AUTO
, TABLE
and SEQUENCE
. See more.
有四个可能的值strategy
的元素@GeneratedValue
注释:IDENTITY
,AUTO
,TABLE
和SEQUENCE
。 查看更多。
So to answer Part 2of your question, the code snippet is indicating that the value of userId
will be obtained through a sequence in the database.
因此,要回答问题的第 2 部分,代码片段表明userId
将通过数据库中的序列获取的值。
The generator
element of the @GeneratedValue
annotation denotes the name of the primary key generator. In Part1of your question, the code snippet indicates that a generator
named increment
will be used to obtain the primary key value. increment
is then defined in the next annotation @GenericGenerator
. @GenericGenerator
is a hibernate annotation used to denote a custom generator, which can be a class or shortcut to a generator supplied by Hibernate. increment
is a shortcut to a Hibernate generator that:
注释的generator
元素@GeneratedValue
表示主键生成器的名称。在您问题的第 1部分中,代码片段表明将使用generator
命名increment
来获取主键值。 increment
然后在下一个注释中定义@GenericGenerator
。 @GenericGenerator
是用于表示自定义生成器的 hibernate 注释,它可以是 Hibernate 提供的生成器的类或快捷方式。 increment
是 Hibernate 生成器的快捷方式:
generates identifiers of type long, short or int that are unique only when no other process is inserting data into the same table. Do not use in a cluster.
生成 long、short 或 int 类型的标识符,这些标识符仅在没有其他进程将数据插入同一个表时才是唯一的。不要在集群中使用。
In the Third Partof your question, the code uses a hilo
Hibernate generator that:
在问题的第三部分中,代码使用了一个hilo
Hibernate 生成器:
uses a hi/lo algorithm to efficiently generate identifiers of type long, short or int, given a table and column (by default hibernate_unique_key and next_hi respectively) as a source of hi values. The hi/lo algorithm generates identifiers that are unique only for a particular database.
给定一个表和列(默认分别为 hibernate_unique_key 和 next_hi)作为 hi 值的来源,使用 hi/lo 算法有效地生成 long、short 或 int 类型的标识符。hi/lo 算法生成仅对特定数据库唯一的标识符。
回答by Mohd Faizan Khan
@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;
- @GeneratedValue is used only to get the generated value. The two arguments strategyand generatorare used to define how the value is obtained.
- @GenericGenerator is used to map a user defined sequence generator with your hibernate session.
- You can also use @SequenceGenerator which i have commented in my code. This is not a simple sequence generator but a generator which work on HILOalgorithm. Due to which you will find a lot of gaps in your sequence, like your first value will start from 50 because the default allocation size is 50.
- @GeneratedValue 仅用于获取生成的值。两个参数strategy和generator用于定义如何获取值。
- @GenericGenerator 用于将用户定义的序列生成器映射到您的休眠会话。
- 您还可以使用我在代码中注释的 @SequenceGenerator。这不是一个简单的序列生成器,而是一个适用于HILO算法的生成器。因此,您会发现序列中有很多差距,例如您的第一个值将从 50 开始,因为默认分配大小为 50。
So its better to use @GenericGenerator for your own architecture. But if you are bound to use @SequenceGenerator you have to manually edit your sequence to have two more attributes allocationSize=1and initialValue=1. And to work with these attributes you need to add apropert in your hibernate.cfg.xmlfile
因此,最好将 @GenericGenerator 用于您自己的架构。但是,如果您必须使用 @SequenceGenerator,则必须手动编辑序列以拥有另外两个属性allocationSize=1和initialValue=1。要使用这些属性,您需要在hibernate.cfg.xml文件中添加 apropert
<property name="hibernate.id.new_generator_mappings">true</property>
回答by naXa
To extend the @kevin-bowersox's answer.
Relationships between the Hibernate primary key generation strategies and specific generator respectively, as specified in org.hibernate.id.IdentifierGeneratorFactory
扩展@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);
}
In Hibernate 4.3 I've found org.hibernate.id.factory.internal.DefaultIdentifierGeneratorFactory
class with 3 more strategies:
在 Hibernate 4.3 中,我发现org.hibernate.id.factory.internal.DefaultIdentifierGeneratorFactory
类还有 3 个策略:
register("uuid2", UUIDGenerator.class);
register("enhanced-sequence", SequenceStyleGenerator.class);
register("enhanced-table", TableGenerator.class);
The above fifteen strategies, plus native
, are sixteen generation strategies supported in Hibernate by default.
以上十五种策略,加上native
,是Hibernate默认支持的十六种生成策略。
Example with native
:
示例native
:
@GeneratedValue(generator = "nativeGenerator")
@GenericGenerator(name = "nativeGenerator", strategy = "native")