2010-03-22 32 views
5

我們是JPA的新手,試圖建立一個非常簡單的一對多關係,其中一個名爲Message的POJO可以具有由一個連接表名爲GROUP_ASSOC。下面是DDL:聲明的持久性策略不支持字段的類型「OneToMany」

CREATE TABLE "APP"."MESSAGE" (
     "MESSAGE_ID" INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1) 
    ); 

ALTER TABLE "APP"."MESSAGE" ADD CONSTRAINT "MESSAGE_PK" PRIMARY KEY ("MESSAGE_ID"); 

CREATE TABLE "APP"."GROUP_ASSOC" (
     "GROUP_ID" INTEGER NOT NULL, 
     "MESSAGE_ID" INTEGER NOT NULL 
    ); 

ALTER TABLE "APP"."GROUP_ASSOC" ADD CONSTRAINT "GROUP_ASSOC_PK" PRIMARY KEY ("MESSAGE_ID", "GROUP_ID"); 

ALTER TABLE "APP"."GROUP_ASSOC" ADD CONSTRAINT "GROUP_ASSOC_FK" FOREIGN KEY ("MESSAGE_ID") 
    REFERENCES "APP"."MESSAGE" ("MESSAGE_ID");

這裏是POJO:

@Entity 
@Table(name = "MESSAGE") 
public class Message { 
    @Id 
    @Column(name = "MESSAGE_ID") 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private int messageId; 

    @OneToMany(fetch=FetchType.LAZY, cascade=CascadeType.PERSIST) 
    private List groupIds; 

    public int getMessageId() { 
     return messageId; 
    } 
    public void setMessageId(int messageId) { 
     this.messageId = messageId; 
    } 
    public List getGroupIds() { 
     return groupIds; 
    } 
    public void setGroupIds(List groupIds) { 
     this.groupIds = groupIds; 
    } 
}

我知道,因爲沒有@Column映射GROUP_ASSOC.GROUP_ID的組id屬性,但這是錯誤的希望這說明了什麼,我們正在努力去做。當我們運行以下測試代碼時,我們得到<openjpa-1.2.3-SNAPSHOT-r422266:907835 fatal user error> org.apache.openjpa.util.MetaDataException: The type of field "pojo.Message.groupIds" isn't supported by declared persistence strategy "OneToMany". Please choose a different strategy.

Message msg = new Message(); 
List groups = new ArrayList(); 
groups.add(101); 
groups.add(102); 
EntityManager em = Persistence.createEntityManagerFactory("TestDBWeb").createEntityManager(); 
em.getTransaction().begin(); 
em.persist(msg); 
em.getTransaction().commit();

幫助!

回答

3

當您使用JPA的工作,你應該考慮的對象之間的對象和關係,你應該你的對象模型,而不是ids,映射到關係模型(這是可能的基本價值觀的List@ElementCollection在JPA 2.0地圖儘管如此,但我剛剛說的仍然適用)。

這裏,(假設這確實是一個一個一對多關係和GroupAssoc一個之間Message並沒有太多的一對多關係之間MessageGroup實體),你應該有這樣的事情:

@Entity 
@Table(name = "MESSAGE") 
public class Message implements Serializable { 
    @Id 
    @Column(name = "MESSAGE_ID") 
    @GeneratedValue(strategy = GenerationType.IDENTITY)  
    private Long messageId; 

    @OneToMany(fetch=FetchType.LAZY, cascade=CascadeType.PERSIST)  
    private List<GroupAssoc> groupAssocs = new ArrayList<GroupAssoc>(); 

    public Long getMessageId() { 
     return messageId; 
    } 
    public void setMessageId(Long messageId) { 
     this.messageId = messageId; 
    } 

    public List<GroupAssoc> getGroupAssocs() { 
     return groupAssocs; 
    } 
    public void setGroupAssocs(List<GroupAssoc> groupAssocs) { 
     this.groupAssocs = groupAssocs; 
    } 

    // equals() and hashCode() 
} 

而另一個實體GroupAssoc

PS:您的DDL真的看起來像(M:N)MESSAGEGROUP之間的關係(或我不明白的GROUP_ASSOC PK的約束),但你沒有表現出對GROUP_ID任何FK約束,所以我不是100%確定的。但是,如果是這樣的話,那麼你應該使用@ManyToMany而不是@OneToMany

+0

非常感謝您的幫助。我應該提到我們的應用程序需要顯示groupIds(在UI中),並且groupId的列表是我們最終需要通過消息查詢的。我認爲這是M:N的關係,因爲兩次按摩可能共享相同的組ID。 – Lightbeard 2010-03-23 02:12:31

+0

我的DDL是我最好的猜測,因爲如何有效地建模這個整數列表,所以可能有問題(我是一個UI開發人員而不是DBA)。創建一個單獨的'GroupAssoc' pojo似乎很麻煩,特別是如果我們必須創建第三個標識類(因爲它有一個組合主鍵)來查詢給定消息的groupIds列表,這似乎很麻煩。 – Lightbeard 2010-03-23 02:12:52

+0

@Robert您不必創建第三個實體,JPA就可以在數據庫級別抽象實現。所以你會得到一個'GroupAssoc'列表並迭代列表來獲取每個id。 – 2010-03-23 02:40:00