У нас есть pojo, которому нужен список целых чисел. В качестве примера, я создал Message
pojo и хотел бы связать список groupIds
(эти идентификаторы должны быть запрошены и отображены в пользовательском интерфейсе). Поэтому в идеале мы хотели бы иметь возможность сделать что-то вроде этого:
Message msg = em.find(Message.class, 101);
List<Integer> groupIds = msg.getGroupIds();
У меня сложилось впечатление, что для этого потребуется только одно pojo с JPA, но согласно обсуждению здесь , мне нужно создать второе pojo, потому что JPA работает с точки зрения объектов вместо примитивных типов.
Из этого обсуждения я попробовал следующий пример кода, но я получаю ошибку openjpa-1.2.3-SNAPSHOT-r422266:907835 fatal user error: org.apache.openjpa.util.MetaDataException: The type of field "pojo.Group.messageId" isn't supported by declared persistence strategy "ManyToOne". Please choose a different strategy.
DDL:
CREATE TABLE "APP"."MESSAGE" (
"MESSAGE_ID" INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1),
"AUTHOR" CHAR(20) NOT NULL
);
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");
POJOs:
@Entity
@Table(name = "MESSAGE")
public class Message {
@Id
@Column(name = "MESSAGE_ID")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long messageId;
@OneToMany
private List<Group> groups = new ArrayList<Group>();
@Column(name = "AUTHOR")
private String author;
// getters/setters ommitted
}
@Entity
@IdClass(pojo.Group.GroupKey.class)
@Table(name = "GROUP_ASSOC")
public class Group {
@Id
@Column(name = "GROUP_ID")
private Long groupId;
@Id
@Column(name = "MESSAGE_ID")
@ManyToOne
private Long messageId;
public static class GroupKey {
public Long groupId;
public Long messageId;
public boolean equals(Object obj) {
if(obj == this) return true;
if(!(obj instanceof Group)) return false;
Group g = (Group) obj;
return g.getGroupId() == groupId && g.getMessageId() == messageId;
}
public int hashCode() {
return ((groupId == null) ? 0 : groupId.hashCode())
^ ((messageId == null) ? 0 : messageId.hashCode());
}
}
// getters/setters ommitted
}
Тестовый код:
EntityManager em = Persistence.createEntityManagerFactory("JPATest").createEntityManager();
em.getTransaction().begin();
Message msg = new Message();
msg.setAuthor("Paul");
em.persist(msg);
List<Group> groups = new ArrayList<Group>();
Group g1 = new Group();
g1.setMessageId(msg.getMessageId());
Group g2 = new Group();
g2.setMessageId(msg.getMessageId());
msg.setGroups(groups);
em.getTransaction().commit();
Все это кажется смешным - 3 класса (если вы включаете составной класс идентификации GroupKey) для моделирования списка целых чисел - не существует ли более элегантного решения?