2010-03-22 55 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