默认情况下,我可以配置Hibernate为每个表创建单独的序列吗?

默认情况下,我可以配置Hibernate为每个表创建单独的序列吗?,hibernate,orm,code-generation,ddl,Hibernate,Orm,Code Generation,Ddl,Hibernate默认情况下创建一个全局序列,用于为所有表生成ID(在PostgreSQL的情况下),该序列可以扩展非常糟糕的IMHO。虽然我可以为每个实体类型指定要使用的序列,但我不喜欢这样做。我不喜欢显式命名序列并强制使用序列作为生成器策略,因为我希望hibernate为可能根本不支持序列的数据库生成DDL。单一的全局序列还使得无法使用32位int作为主键,这意味着我必须将所有int id转换为long类型。Hibernate意味着是独立于数据库的ORM解决方案,但在迁移到另一个数据库供应商

Hibernate默认情况下创建一个全局序列,用于为所有表生成ID(在PostgreSQL的情况下),该序列可以扩展非常糟糕的IMHO。虽然我可以为每个实体类型指定要使用的序列,但我不喜欢这样做。我不喜欢显式命名序列并强制使用序列作为生成器策略,因为我希望hibernate为可能根本不支持序列的数据库生成DDL。单一的全局序列还使得无法使用32位int作为主键,这意味着我必须将所有int id转换为long类型。

Hibernate意味着是独立于数据库的ORM解决方案,但在迁移到另一个数据库供应商时,一些关键问题出现了。其中之一是底层数据库的自动ID生成。MySQL、Oracle和MS SQL Server都使用不同的技术为主键生成自动ID。因此,当我们开始迁移时,我们会面临很多问题,额外的工作,而这不应该发生

在Hibernate 3.2.3之前,Hibernate没有合适的解决方案,但是在3.2.3版本中,Hibernate的伙计们提供了这样的便携式ID生成器,它可以在任何数据库上正常工作。这两个是,

  • org.hibernate.id.enhanced.SequenceStyleGenerator
“实现可移植性的方法是,实际上您并不关心是否在数据库中实际使用序列;实际上,您只希望生成类似序列的值。在支持序列的数据库上,SequenceStyleGenerator实际上将使用SEQUENCE作为值生成器;对于不支持序列的数据库,SequenceStyleGenerator将使用SEQUENCE作为值生成器S、 它将使用一个单行表作为值生成器,但与序列值生成器具有相同的确切特性(即它始终在单独的事务中处理序列表)”

  • org.hibernate.id.enhanced.TableGenerator
虽然TableGenerator并非专门针对可移植性,但它肯定可以在所有数据库中使用。它使用多行表,其中行由(可配置的)键控sequence_name列;一种方法是让每个实体在表中定义一个唯一的sequence_name值,以分割其标识符值。它起源于较旧的org.hibernate.id.MultipleHiLoPerTableGenerator,并使用基本相同的表结构。然而,MultipleHiLoPerTableGenerator本质上对在价值生成过程中,添加了这个新的TableGenerator,以便能够利用可插拔优化器

在所有数据库中使用Hibernate序列的示例实体。

@Entity
@Table(name = "author")
public class Author implements java.io.Serializable {

 // Fields

 private Integer id;
 private String name;
 private Date birthDate;
 private Date deathDate;
 private String bio;
 private String wikiUrl;
 private String imagePath;
 private Boolean isFeatured;
 private Long totalContent;
 private Set<Content> contents = new HashSet<Content>(0);

 // Constructors

 /** default constructor */
 public Author() {
 }

 // Property accessors
 @Id
 @GeneratedValue(generator = "Author_SequenceStyleGenerator")
 @GenericGenerator(name = "Author_SequenceStyleGenerator", strategy = "org.hibernate.id.enhanced.SequenceStyleGenerator",
 parameters = {
 @Parameter(name = "sequence_name", value = "Author_SEQ"),
 @Parameter(name = "optimizer", value = "hilo"),
 @Parameter(name = "initial_value", value = "1"),
 @Parameter(name = "increment_size", value = "1") }
 )
 @Column(name = "id", unique = true, nullable = false, length = 11)
 public Integer getId() {
 return this.id;
 }

 public void setId(Integer id) {
 this.id = id;
 }

 @Column(name = "name", length = 50)
 public String getName() {
 return this.name;
 }

 public void setName(String name) {
 this.name = name;
 }

 @Temporal(TemporalType.DATE)
 @Column(name = "birth_date", length = 10)
 public Date getBirthDate() {
 return this.birthDate;
 }

 public void setBirthDate(Date birthDate) {
 this.birthDate = birthDate;
 }

 @Temporal(TemporalType.DATE)
 @Column(name = "death_date", length = 10)
 public Date getDeathDate() {
 return this.deathDate;
 }

 public void setDeathDate(Date deathDate) {
 this.deathDate = deathDate;
 }

 @Column(name = "bio", length = 65535)
 public String getBio() {
 return this.bio;
 }

 public void setBio(String bio) {
 this.bio = bio;
 }

 @Column(name = "wiki_url", length = 128)
 public String getWikiUrl() {
 return this.wikiUrl;
 }

 public void setWikiUrl(String wikiUrl) {
 this.wikiUrl = wikiUrl;
 }

 @Column(name = "image_path", length = 50)
 public String getImagePath() {
 return this.imagePath;
 }

 public void setImagePath(String imagePath) {
 this.imagePath = imagePath;
 }

 @Column(name = "is_featured")
 public Boolean getIsFeatured() {
 return this.isFeatured;
 }

 public void setIsFeatured(Boolean isFeatured) {
 this.isFeatured = isFeatured;
 }

 @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "author")
 public Set<Content> getContents() {
 return this.contents;
 }

 public void setContents(Set<Content> contents) {
 this.contents = contents;
 }

 @Transient
 public Long getTotalContent() {
 return totalContent;
 }

 public void setTotalContent(Long totalContent) {
 this.totalContent = totalContent;
 }

}
}
@实体
@表(name=“author”)
公共类作者实现java.io.Serializable{
//田地
私有整数id;
私有字符串名称;
私人生日;
私人日期死亡日期;
私人字符串bio;
私有字符串wikiUrl;
私有字符串路径;
私有布尔型;
私人内容;
私有集内容=新哈希集(0);
//建设者
/**默认构造函数*/
公共作者(){
}
//属性访问器
@身份证
@GeneratedValue(generator=“Author\u SequenceStyleGenerator”)
@GenericGenerator(name=“Author\u SequenceStyleGenerator”,strategy=“org.hibernate.id.enhanced.SequenceStyleGenerator”,
参数={
@参数(name=“sequence\u name”,value=“Author\u SEQ”),
@参数(name=“optimizer”,value=“hilo”),
@参数(name=“initial_value”,value=“1”),
@参数(name=“increment\u size”,value=“1”)}
)
@列(name=“id”,unique=true,nullable=false,length=11)
公共整数getId(){
返回此.id;
}
公共无效集合id(整数id){
this.id=id;
}
@列(name=“name”,长度=50)
公共字符串getName(){
返回此.name;
}
公共void集合名(字符串名){
this.name=名称;
}
@时态(TemporalType.DATE)
@列(name=“出生日期”,长度=10)
公共日期getBirthDate(){
返回此项。生日;
}
公共无效设置出生日期(日期出生日期){
this.birthDate=生日;
}
@时态(TemporalType.DATE)
@列(name=“死亡日期”,长度=10)
公共日期getDeathDate(){
返回此。死亡日期;
}
公共无效设置死亡日期(日期死亡日期){
this.deathDate=死亡日期;
}
@列(name=“bio”,长度=65535)
公共字符串getBio(){
返回此.bio;
}
公共void setBio(字符串bio){
this.bio=bio;
}
@列(name=“wiki\u url”,长度=128)
公共字符串getWikiUrl(){
返回this.wikiUrl;
}
public void setWikiUrl(字符串wikiUrl){
this.wikiUrl=wikiUrl;
}
@列(name=“image\u path”,长度=50)
公共字符串getImagePath(){
返回此.imagePath;
}
公共void setImagePath(字符串imagePath){
this.imagePath=imagePath;
}
@列(name=“is_特色”)
公共布尔getIsFeatured(){
返回此.isFeatured;
}
public void setIsFeatured(布尔值isFeatured){
this.isFeatured=isFeatured;
}
@OneToMany(cascade=CascadeType.ALL,fetch=FetchType.LAZY,mappedBy=“author”)
公共集getContents(){
返回此.contents;
}
公共无效集合内容(集合内容){
this.contents=目录;
}
@短暂的
公共长getTotalContent(){
返回全部内容;
}
公共无效setTotalContent(长totalContent){
this.totalContent=totalContent;
}
}
}

如果没有明确指定每个实体的序列的唯一原因是您希望在不支持序列的数据库上使用DDL,那么这可能是您的解决方案:

@Id
@SequenceGenerator(name = "your_table_id_seq", sequenceName = "your_table_id_seq")
@GeneratedValue(strategy = GenerationType.AUTO, generator = "your_table_id_seq")
@Column(name = "your_table_id")
public Long getId() {
    return id;
}

这将适用于不带序列的数据库(策略自动)。

这篇文章的开头描述是原始代码编写者Steve Ebersole的剪贴,他在博客中介绍了这一特性,请参阅Look there了解更多详细信息。是的,描述来自hibernate的官方文档。