The type of field isn't supported by declared persistence strategy “OneToMany”
Question
We are new to JPA and trying to setup a very simple one to many relationship where a pojo called Message can have a list of integer group id's defined by a join table called GROUP_ASSOC
. Here is the DDL:
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");
Here is the 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;
}
}
I know this is wrong as there is no @Column
mapping to GROUP_ASSOC.GROUP_ID
for the groupIds property, but hopefully this illustrates what we are trying to do. When we run the following test code we get <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();
Help!
Solution
When you are working with JPA, you should think Object and relations between Objects and you should map your Object model, not ids
, to your relational model (it is possible to map a List
of basic values with @ElementCollection
in JPA 2.0 though but what I said just before still applies).
Here, (assuming this really is a one-to-many relation between Message
and GroupAssoc
and not a many-to-many relation between Message
and Group
entities) you should have something like this:
@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()
}
And another entity for GroupAssoc
.
PS: Your DDL really looks like a (M:N) relation between MESSAGE
and GROUP
(or I don't understand the PK constraint of GROUP_ASSOC
) but you didn't show any FK constraint on GROUP_ID
so I'm not 100% sure. But if that's the case, then you should use an @ManyToMany
instead of @OneToMany
.