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

Xiè*_*léi 6 orm ddl code-generation hibernate

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

Fai*_*sra 4

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

\n\n

在 Hibernate 3.2.3 之前,Hibernate 没有提供适当的解决方案,但在 3.2.3 版本中,Hibernate 人员使得提供这种可在任何数据库上运行良好的便携式 ID 生成器成为可能。两者如下,

\n\n
    \n
  • org.hibernate.id.enhanced.SequenceStyleGenerator
  • \n
\n\n

\xe2\x80\x9c实现可移植性的方法是,您实际上并不关心是否在数据库中实际使用 SEQUENCE; 实际上,您只需要类似序列的值生成。在支持 SEQUENCES 的数据库上,SequenceStyleGenerator 实际上将使用 SEQUNCE 作为值生成器;对于那些不支持SEQUENCES的数据库,它将使用单行表作为值生成器,但具有与SEQUENCE值生成器相同的特性(即它始终在单独的事务中处理序列表) \xe2\x80\x9d。

\n\n
    \n
  • org.hibernate.id.enhanced.TableGenerator
  • \n
\n\n

虽然没有专门针对可移植性,但 TableGenerator 当然可以在所有数据库中使用。它使用多行表,其中行由(可配置的)sequence_name 列作为键;一种方法是让每个实体在表中定义唯一的sequence_name值来分段其标识符值。它源自较旧的 org.hibernate.id.MultipleHiLoPerTableGenerator,并使用基本相同的表结构。然而,虽然 MultipleHiLoPerTableGenerator 本质上将 hi-lo 算法应用于值生成,但添加了这个新的 TableGenerator 以便能够利用可插入优化器。

\n\n

示例实体 哪种用法,Hibernate 跨所有数据库的序列。

\n\n
@Entity\n@Table(name = "author")\npublic class Author implements java.io.Serializable {\n\n // Fields\n\n private Integer id;\n private String name;\n private Date birthDate;\n private Date deathDate;\n private String bio;\n private String wikiUrl;\n private String imagePath;\n private Boolean isFeatured;\n private Long totalContent;\n private Set<Content> contents = new HashSet<Content>(0);\n\n // Constructors\n\n /** default constructor */\n public Author() {\n }\n\n // Property accessors\n @Id\n @GeneratedValue(generator = "Author_SequenceStyleGenerator")\n @GenericGenerator(name = "Author_SequenceStyleGenerator", strategy = "org.hibernate.id.enhanced.SequenceStyleGenerator",\n parameters = {\n @Parameter(name = "sequence_name", value = "Author_SEQ"),\n @Parameter(name = "optimizer", value = "hilo"),\n @Parameter(name = "initial_value", value = "1"),\n @Parameter(name = "increment_size", value = "1") }\n )\n @Column(name = "id", unique = true, nullable = false, length = 11)\n public Integer getId() {\n return this.id;\n }\n\n public void setId(Integer id) {\n this.id = id;\n }\n\n @Column(name = "name", length = 50)\n public String getName() {\n return this.name;\n }\n\n public void setName(String name) {\n this.name = name;\n }\n\n @Temporal(TemporalType.DATE)\n @Column(name = "birth_date", length = 10)\n public Date getBirthDate() {\n return this.birthDate;\n }\n\n public void setBirthDate(Date birthDate) {\n this.birthDate = birthDate;\n }\n\n @Temporal(TemporalType.DATE)\n @Column(name = "death_date", length = 10)\n public Date getDeathDate() {\n return this.deathDate;\n }\n\n public void setDeathDate(Date deathDate) {\n this.deathDate = deathDate;\n }\n\n @Column(name = "bio", length = 65535)\n public String getBio() {\n return this.bio;\n }\n\n public void setBio(String bio) {\n this.bio = bio;\n }\n\n @Column(name = "wiki_url", length = 128)\n public String getWikiUrl() {\n return this.wikiUrl;\n }\n\n public void setWikiUrl(String wikiUrl) {\n this.wikiUrl = wikiUrl;\n }\n\n @Column(name = "image_path", length = 50)\n public String getImagePath() {\n return this.imagePath;\n }\n\n public void setImagePath(String imagePath) {\n this.imagePath = imagePath;\n }\n\n @Column(name = "is_featured")\n public Boolean getIsFeatured() {\n return this.isFeatured;\n }\n\n public void setIsFeatured(Boolean isFeatured) {\n this.isFeatured = isFeatured;\n }\n\n @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "author")\n public Set<Content> getContents() {\n return this.contents;\n }\n\n public void setContents(Set<Content> contents) {\n this.contents = contents;\n }\n\n @Transient\n public Long getTotalContent() {\n return totalContent;\n }\n\n public void setTotalContent(Long totalContent) {\n this.totalContent = totalContent;\n }\n\n}\n}\n
Run Code Online (Sandbox Code Playgroud)\n

  • 本文开头的描述是来自原始代码编写者 Steve Ebersole 的剪切和粘贴,他在 http://in.relation.to/2082.lace 上发表了有关此功能的博客,请在此处查看更多详细信息。 (2认同)