2011-07-09 69 views
6

休眠默認創建該秤非常不好IMHO其用於產生用於所有的表,(在對PostgreSQL的情況下)ID的globel序列。雖然我可以爲每個實體類型指定使用哪個序列,但我不喜歡這樣做。我不喜歡明確命名序列並強制使用序列作爲生成器策略,因爲我希望hibernate爲可能不支持序列的數據庫生成DDL。單個全局序列也使得不可能使用32位int作爲主鍵,這意味着我必須將所有int id轉換爲long類型。我可以配置Hibernate默認爲每個表創建單獨的序列嗎?

回答

4

Hibernate的意思是獨立於數據庫的ORM解決方案,但在遷移到其他數據庫廠商的一些關鍵問題到達。其中之一是底層數據庫的Auto ID生成。 MySQL,Oracle & MS SQL Server都使用不同的技術爲主鍵生成自動ID。所以,當我們開始遷移時,我們面臨很多問題,而不應該是這樣的額外工作。

此前的Hibernate 3.2.3得到了由休眠沒有妥善的解決辦法,但在3.2.3版休眠傢伙使我們能夠提供這種便攜式ID生成的任何數據庫上運行良好。這兩者是以下,

  • org.hibernate.id.enhanced.SequenceStyleGenerator

「的辦法才能可移植性真的是你不關心你是否在物理上使用序列中的數據庫;真的,你只是想要一個像序列一樣的值生成。在支持SEQUENCES的數據庫上,SequenceStyleGenerator實際上將使用SEQUNCE作爲值生成器;對於不支持SEQUENCES的數據庫,它將使用單行表作爲值生成器,但與SEQUENCE值生成器具有相同的確切特徵(即它始終在單獨的事務中處理序列表) 」。

  • org.hibernate.id.enhanced.TableGenerator

,而沒有具體靶向便攜性,TableGenerator當然可以在所有數據庫中。它使用一個多行表,其中行由(可配置的)sequence_name列鍵入;一種方法是讓每個實體在表中定義唯一的sequence_name值來分割其標識符值。它由早期的org.hibernate.id.MultipleHiLoPerTableGenerator發展而來,基本上使用相同的表結構。然而,雖然MultipleHiLoPerTableGenerator固有地將Hi-Lo算法應用於值生成,但新增的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; 
} 

} 
} 
+2

在這篇文章的開頭描述是剪切和粘貼從原來的代碼作家史蒂夫·埃伯索爾,誰在http://in.relation.to/2082.lace博客上講述這個功能看,那有更多的細節。 –

+0

是的,描述來自hibernate的官方文檔。 –

2

如果未明確指定每個實體的序列的唯一原因是你想要使用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; 
} 

這是去工作的數據庫W/O序列(策略AUTO)。

相關問題