有时候我会一起找到它们,有时候只是一个人......有时候它们似乎也是这样。
有什么区别?
以下是三个例子。他们有什么不同的做法?为什么我不能只为所有这些使用@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>();
答案 0 :(得分:73)
使用ORM时,通常需要生成主键值。
@GeneratedValue
注释表示生成了必须使用@Id
注释的列的值。注释中的元素strategy
和generator
描述了如何获取生成的值。
strategy
注释上的@GeneratedValue
元素有四个可能的值:IDENTITY
,AUTO
,TABLE
和SEQUENCE
。 See more
因此,要回答问题的第2部分,代码段会指示将通过数据库中的序列获取userId
的值。
generator
注释的@GeneratedValue
元素表示主键生成器的名称。在您的问题的第1部分中,代码段表示将使用名为generator
的{{1}}来获取主键值。然后在下一个注释increment
中定义increment
。 @GenericGenerator
是一个用于表示自定义生成器的hibernate注释,它可以是Hibernate提供的生成器的类或快捷方式。 @GenericGenerator
是Hibernate生成器的快捷方式:
生成long,short或int类型的标识符,这些标识符仅是唯一的 当没有其他进程将数据插入同一个表时。不要 在集群中使用。
在您的问题的第三部分中,代码使用increment
Hibernate生成器:
使用hi / lo算法有效地生成类型的标识符 给定表和列(默认情况下为long,short或int) hibernate_unique_key和next_hi分别作为hi的来源 值。 hi / lo算法生成仅唯一的标识符 对于特定的数据库。
答案 1 :(得分: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);
}
在Hibernate 4.3中,我发现了org.hibernate.id.factory.internal.DefaultIdentifierGeneratorFactory
类,还有3个策略:
register("uuid2", UUIDGenerator.class);
register("enhanced-sequence", SequenceStyleGenerator.class);
register("enhanced-table", TableGenerator.class);
以上十五种策略加上native
是默认情况下Hibernate支持的十六代策略。
native
的示例:
@GeneratedValue(generator = "nativeGenerator")
@GenericGenerator(name = "nativeGenerator", strategy = "native")
答案 2 :(得分:2)
@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;
因此,最好将@GenericGenerator用于您自己的架构。但是,如果您必须使用@SequenceGenerator,则必须手动编辑序列,以便再增加两个属性 allocationSize = 1 和 initialValue = 1 。要使用这些属性,您需要在hibernate.cfg.xml文件中添加apropert
<property name="hibernate.id.new_generator_mappings">true</property>