@GeneratedValue和@GenericGenerator之间的区别

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

有什么不同?

这里有三个例子。 他们做什么不同? 为什么我不能仅仅使用@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>(); 

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

@GeneratedValue注解表示必须使用@Id注释的列的值被生成。 注释中的元素strategygenerator描述如何获得生成的值。

@GeneratedValue批注中有四个可能的strategy元素值: IDENTITYAUTOTABLESEQUENCE 。 查看更多 。

所以要回答你的问题的第二部分 ,代码片断指出了userId的值将通过数据库中的一个序列获得。

@GeneratedValue批注的generator元素表示主键生成器的名称。 在你的问题的第一部分 ,代码片断指出一个名为incrementgenerator将被用来获得主键值。 然后在下一个注解@GenericGenerator定义increment@GenericGenerator是一个hibernate注释,用来表示一个自定义生成器,它可以是Hibernate提供的生成器的类或快捷方式。 increment是一个Hibernate生成器的快捷方式:

生成long,short或inttypes的唯一标识符,只有在没有其他进程将数据插入到同一个表中时才是唯一的。 不要在群集中使用。

在你的问题的第三部分 ,代码使用hilo Hibernate生成器:

使用hi / loalgorithm来高效地生成long,short或inttypes的标识符,给定一个表和列(分别默认为hibernate_unique_key和next_hi)作为hi值的来源。 hi / loalgorithm生成仅对特定数据库唯一的标识符。

 @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仅用于获取生成的值。 两个参数策略生成器用于定义如何获得值。
  • @GenericGenerator用来映射用户定义的序列发生器与你的hibernate会话。
  • 您也可以使用@SequenceGenerator,我已经在我的代码中进行了评论。 这不是一个简单的序列生成器,而是一个在HILOalgorithm上工作的生成器。 由此你会发现你的序列中有很多空白,就像你的第一个值从50开始,因为默认的分配大小是50。

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

 <property name="hibernate.id.new_generator_mappings">true</property> 

扩展@ kevin-bowersox的答案。
org.hibernate.id.IdentifierGeneratorFactory指定的Hibernate主键生成策略和特定生成器之间的关系

 static { GENERATORS.put("uuid", UUIDHexGenerator.class); GENERATORS.put("hilo", TableHiLoGenerator.class); 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); } 

上述十二种策略,加上native ,默认情况下是Hibernate支持的十三代策略。

native示例:

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