2012-01-18 54 views
2

我用SchemaExport爲創建我的表像這樣如何最好地處理關聯表/外鍵與休眠?

Configuration config = new Configuration(); 
    config.addAnnotatedClass(Categories.class); 
    config.addAnnotatedClass(Article.class); 
    config.configure(); 
     new SchemaExport(config).create(true, true); 

Categories.java和Article.java的重要的部分是這些:

Article.java 

    @Id 
@GeneratedValue 
public Long getId() { 
    return id; 
} 

    @OneToMany(cascade = CascadeType.ALL) 
public Set<Categories> getCategories() { 
    return categories; 
} 

Categories.java 

    @Id 
@GeneratedValue 
public Long getId() { 
    return id; 
} 

    @ManyToOne(cascade = CascadeType.ALL) 
public Article getArticleCategories() { 
    return articleCategories; 
} 

運行時,模式導出生成三個表:第一條,類別和文章類別。 article_categories是一個關聯表,其中兩個主鍵與Article和Categories中的鍵匹配。只有文章和類別已被添加到我的ApplicationContext.xml中的SessionFactory,因爲我明顯沒有第三個表作爲類生成後的類。我寫了這個HQL:

"from Article a, article_categories ac, Categories c where ac.Article_id = a.id and ac.categories_id = c.id and c.category = 'p'" 

Hibernate無法運行它,因爲article_categories沒有被映射。我需要映射它嗎?運行本機SQL而不是HQL可能的替代方案,還是應該避免關聯表一起?這個問題的解決方案是什麼?

回答

2

HQL不適用於表格。它適用於實體及其關聯。在HQL查詢中的實體之間創建連接,Hibernate將使用連接表爲您生成適當的SQL。

實施例:

select a from Article a 
inner join a.categories c 
where c.category = :categoryName 

讀取(至少)the HQL section of the reference manual

附註:實體的名稱應該是單數:類別而不是類別。因此,一篇文章有​​一個Set<Category>,名爲categories。更容易閱讀和理解這種方式。類別的category字段應該被命名爲name:它是類別的名稱,而不是其類別。

1

不太確定,如果您在原始數據庫或導出中有錯誤。我們使用相同的方法,但之後重構表格。 (我會嘗試找到我們使用的腳本,如果你需要它,並且明天回到這個腳本)

無論如何:你不需要一個實體類來處理你的m:n關係,如果沒有附加字段不是外鍵與其它:

分類:

@ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL) 
@JoinTable(name = "article_categories", 
     joinColumns = { @JoinColumn(name = "article_id", nullable = false, updatable = false) }, 
     inverseJoinColumns = { @JoinColumn(name = "category_id", nullable = false, updatable = false) }) 
private Set<Article> articles; 

在文章:

@ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL) 
    @JoinTable(name = "article_categories", 
      joinColumns = { @JoinColumn(name = "category_id", nullable = false, updatable = false) }, 
      inverseJoinColumns = { @JoinColumn(name = "article_id", nullable = false, updatable = false) }) 
private Set<Category> categories; 

這將創建M:N表。

當我們運行hibernate導出器時,我們實際上得到了一個映射類和一個關鍵類,如果您需要m:n表中的其他列,您將需要這個類。但就像我說的,我必須明天挖掘這個片段。