O tipo de campo não é suportado pela estratégia de persistência declarada "Onetomany"

StackOverflow https://stackoverflow.com/questions/2496131

  •  21-09-2019
  •  | 
  •  

Pergunta

Somos novos no JPA e tentando configurar um muito simples para muitos relacionamentos em que um Pojo chamado Mensagem pode ter uma lista de ID do grupo inteiro definido por uma tabela de junção chamada GROUP_ASSOC. Aqui está o 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");

Aqui está o 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;
    }
}

Eu sei que isso está errado, pois não há @Column mapeamento para GROUP_ASSOC.GROUP_ID Para a propriedade GroupIDs, mas espero que isso ilustre o que estamos tentando fazer. Quando executamos o seguinte código de teste, obtemos <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();

Ajuda!

Foi útil?

Solução

Quando você está trabalhando com o JPA, você deve pensar em objeto e relações entre objetos e deve mapear seu modelo de objeto, não ids, para o seu modelo relacional (é possível mapear um List de valores básicos com @ElementCollection No JPA 2.0, mas o que eu disse pouco antes ainda se aplica).

Aqui, (assumindo que isso realmente é um um para muitos relação entre Message e GroupAssoc e não um muitos para muitos relação entre Message e Group entidades) você deve ter algo assim:

@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()
}

E outra entidade para GroupAssoc.

PS: Seu DDL realmente se parece com uma relação (m: n) entre MESSAGE e GROUP (ou eu não entendo a restrição de PK de GROUP_ASSOC) Mas você não mostrou nenhuma restrição de FK em GROUP_ID Portanto, não tenho 100% de certeza. Mas se for esse o caso, você deve usar um @ManyToMany ao invés de @OneToMany.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top