2010-03-22 17 views
5

Somos nuevos en la APP y tratando de configuración muy sencilla a muchos relación en la que un POJO llamada mensaje puede tener una lista de ID de grupo de número entero definido por una unirse a la tabla llamada GROUP_ASSOC. Aquí está el DDL:El tipo de campo no es compatible con la estrategia de persistencia declarada "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");

Aquí está el 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; 
    } 
}

Sé que esto es un error ya que no hay @Column mapeo a GROUP_ASSOC.GROUP_ID para la propiedad groupIds, pero espero que esto ilustra lo que estamos tratando que hacer. Cuando ejecutamos el siguiente código de prueba obtenemos <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();

¡Ayuda!

Respuesta

3

Cuando se trabaja con JPA, usted debe pensar de objetos y las relaciones entre los objetos y se debe asignar el modelo de objetos, no ids, a su modelo relacional (es posible asignar una List de los valores básicos con @ElementCollection en JPA 2.0 sin embargo, lo que dije antes todavía se aplica).

Aquí, (suponiendo que esto realmente es una uno-a-muchos relación entre Message y GroupAssoc y no un muchos-a-muchos relación entre Message y Group entidades) que debe tener algo como esto:

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

Y otra entidad para GroupAssoc.

PS: Su DDL realmente se parece a una (M: N) relación entre MESSAGE y GROUP (o no entiendo la restricción de PK GROUP_ASSOC) pero no mostraron ninguna restricción FK en GROUP_ID así que estoy no 100% seguro Pero si ese es el caso, entonces debe usar un @ManyToMany en lugar de @OneToMany.

+0

Muchas gracias por su ayuda. Debería haber mencionado que nuestra aplicación necesita mostrar groupIds (en la interfaz de usuario) y que la lista de groupId es lo que finalmente necesitamos consultar por mensaje. Creo que es una relación M: N porque dos masajes pueden compartir los mismos ID de grupo. – Lightbeard

+0

Mi DDL es mi mejor estimación sobre cómo modelar de manera eficiente esta lista de enteros, por lo que puede haber un problema (soy un desarrollador de UI, no un DBA). Parece engorroso crear un pojo 'GroupAssoc' por separado, especialmente si tenemos que crear una tercera clase de identidad (ya que tiene una clave primaria compuesta) solo para consultar una lista de groupIds para un mensaje dado. – Lightbeard

+0

@Robert No tendrías que crear una tercera entidad, JPA resumiría la implementación en el nivel de la base de datos. Entonces obtendrías una Lista de 'GroupAssoc' e iterarías en la lista para obtener cada id. –

Cuestiones relacionadas