@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
注释的列的值被生成。 注释中的元素strategy
和generator
描述如何获得生成的值。
在@GeneratedValue
批注中有四个可能的strategy
元素值: IDENTITY
, AUTO
, TABLE
和SEQUENCE
。 查看更多 。
所以要回答你的问题的第二部分 ,代码片断指出了userId
的值将通过数据库中的一个序列获得。
@GeneratedValue
批注的generator
元素表示主键生成器的名称。 在你的问题的第一部分 ,代码片断指出一个名为increment
的generator
将被用来获得主键值。 然后在下一个注解@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 = 1和initialValue = 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")