2010-01-04 47 views
2

一般情況:第一張表格代表一個 -side,第二張表格代表很多 -side。第三張表格是兩者之間的聯繫。如何實現一對多映射關聯表是所有一對多關係之一嗎?

我的情況:第一個和第二個表是相同的。第三張表作爲所有具有一對多關係的表對之間的鏈接。該第三個表具有附加字段(字符串),其中包含有關2個表的信息。

小例子。假設我們有表格Project和Category(一個類別 - >許多項目)。爲了獲得與類別,我們需要執行一個查詢所有項目:

select project.name, category.name 
from nodeassociation, project, category 
where nodeassociation.association_name='ProjectCategory' 
and nodeassociation.source_id=project.id 
and nodeassociation.sink_id=category.id 

我如何通過JPA的方式指定association_name標準?

UPD:如果JPA不可能,但hibernate處理它,那麼沒關係,什麼是hibernate解決方案?

回答

0

我發現原生查詢合適的溶液。

一言以蔽之:

  1. 我做的項目和類別簡單的映射沒有任何關係(如一對多)
  2. 我添加字段category到項目單位和其標記爲@Transient
  3. 在ProjectDAO我使用原生查詢手動將類別插入到項目中。

關於JPA Native Queriesrelated jboss docs的文章是我的起點。

+0

然後你沒有通過hibernate的關係的自動持久性:如果你添加一個類別到你的項目,並保存項目,你將需要堅持自己的類別和關聯。那麼你會失去很多hibernate的力量。如果使用DAO保存對象,DAO可以完成這項工作,但不能簡單地加載/修改實體,您需要每次加載/修改/保存。也許EntityListener可以以更透明的方式完成這項工作。 – ewernli 2010-01-05 14:06:53

+0

我會閱讀關於EntityListener。你是對的,我在你的評論出現之前就知道這一切,但我沒有看到任何其他出路。 我無法修改數據庫模式。 我的應用程序只能從數據庫中讀取,這使我可以手動更改對象。否則,在應用我的解決方案之前我可能會考慮三次。 – Roman 2010-01-05 14:45:45

1

建議您在association_name列上過濾的數據庫中創建多個視圖,然後根據這些關係在映射中定義多對多關係,並在代碼中強制執行一對多語義。這種使用中間表的情況只能在Hibernate中使用多對多映射來處理。

+0

hibernate的任何例子? – Roman 2010-01-04 14:25:29

0

這通常稱爲qualified association。這種關聯應該用Map而不是List來實現。在hibernate中沒有內置的這些支持。如果你不關心限定符,這個關聯就變成了一個可以用hibernate處理的普通的多對多關係。

但在你的情況下,這不是一個合乎邏輯的關聯。如果我沒有理解好,一個關聯表來表示什麼是真正幾個協會:

  • 如果你可以改變DB模式,以每邏輯協會對錶,問題就消失了。
  • 使用數據庫視圖「模擬」具有單獨的表格(如David M所建議的)是一種替代方案。根據邏輯關聯創建一個視圖,並將其映射爲多對多。
0

的工作也許將有一個多態實體處於休眠NodeAssociation另一種解決方案。每種關聯都會有一個NodeAssociationX實體。然後在ProjectNodeAssociation之間存在一對多關聯。並且每個NodeAssociationX和相應的表/實體(Category等)都有一對多。您可以映射專用字段,以便您可以提供在邏輯級別提供正確視圖的公共getter/setter。

public List getCategories() 
{ 
    List categories = new ArrayList(); 
    for(NodeAssociation na : nodeAssociations) 
    { 
      if(typeof(na) = NodeAssociationCategory) 
      { 
       categories.addAll(((NodeAssociationCategory)na).getCategories()); 
      } 
    } 
    return categories; 
} 

但這很難看。如果可能,嘗試其他解決方案。現在

0
@Entity 
public class Category { 

    private Integer id; 

    @Id 
    public Integer getId() { 
     return this.id; 
    } 

    private LinkBetweenOneCategoryAndManyProject linkClass = new LinkBetweenOneCategoryAndManyProject(); 

    @OneToOne 
    public LinkBetweenOneCategoryAndManyProject getLinkClass() { 
     return this.linkClass; 
    } 

    public void addProject(Project project) { 
     getLinkClass().getProjectList().add(project); 
    } 

    // delegates to LinkClass 
    public String getAdditionalProperty() { 
     getLinkClass().getAdditionalProperty(); 
    } 

} 

我們的項目

@Entity 
public class Project { 

    private Integer id; 

    @Id 
    public Integer getId() { 
     return this.id; 
    } 

} 

現在我們的LinkBetweenOneCategoryAndManyProject類

@Entity 
public class LinkBetweenOneCategoryAndManyProject { 

    private Integer categoryId; 

    private String additionalField; 

    List<Project> projectList; 

    @Id 
    public Integer getCategoryId() { 
     return this.categoryId; 
    } 

    @OneToMany 
    public List<Project> getProjectList() { 
     return projectList; 
    } 

    public String additionalProperty() { 
     return this.additionalField; 
    } 

} 

所以,如果你想要檢索類別和項目,請執行以下操作

select distinct c from Category c left join fetch c.linkedClass lc left join fetch lc.projectList 

負責我想範疇和LinkBetweenOneCategoryAndManyProject之間的關係是OneToOne

問候,

相關問題