2010-07-24 13 views
8

Tengo problemas para configurar las asignaciones de jpa para algunas entidades. Tengo una entidad principal definida como la siguiente.jpa hibernate compilación de clave externa compuesta

@Entity 
@Table(name="EIF_INSTANCE_HDR") 
public class InstanceEntity implements Serializable{ 

private static final long serialVersionUID = 1L; 

@Id 
@GeneratedValue(generator="eif_inst_gen") 
@SequenceGenerator(name="eif_inst_gen",sequenceName="EIF_INSTANCE_SEQ") 
@Column(name = "EAIH_ID") 
private Long eaihid; 
@Column(name = "EAD_ID") 
private Long eadid; 

@OneToMany(targetEntity=InstanceNotifyEntity.class, mappedBy="instance",fetch=FetchType.EAGER, cascade = CascadeType.ALL) 
private List<InstanceNotifyEntity> userDetails = new ArrayList<InstanceNotifyEntity>(); 
} 

entonces tengo una entidad secundaria w/una clave compuesta, y una clave externa a la clave principal de esta tabla como sigue:

@Entity 
@Table(name="EIF_INST_NOTIFIED") 
public class InstanceNotifyEntity implements Serializable{ 

private static final long serialVersionUID = 1L; 

@Id 
@ManyToOne 
@JoinColumn(name="EAIH_ID", referencedColumnName="EAIH_ID") 
private InstanceEntity instance; 

@Id 
@Column(name="USER_ID") 
private Long userId; 
@Column(name="COMMENT_TXT") 
private String commentText; 
} 

Sé que la entidad secundaria es incorrecto, pero yo No estoy seguro de cómo configurar esto para tener un PK compuesto. Sé que necesito configurar una clase PK, pero no estoy seguro de cómo hacer eso cuando un campo es una clave externa para la clase principal. Y una vez configurada, ¿cómo haría el padre referencia a la entidad hija?

Cualquier ayuda es apreciada.

+0

Ver http://stackoverflow.com/questions/2562746/jpa-entity-design-problem/ 2563009 # 2563009 – axtavt

Respuesta

12

Esto se rige por JPA 2 spec sección 2.4.1, "Claves principales correspondientes a identidades derivadas". La sección contiene dos ejemplos directamente aplicables a su problema.

Como se describe en la especificación, hay dos maneras de representar la clave de la entidad secundaria en este caso:

  • @IdClass
  • @EmbeddedId

He aquí un esbozo de la forma EmbeddedId. Elegí EmbeddedId arbitrariamente, pero la elección entre IdClass y EmbeddedId es significativa. Puede elegir de manera diferente.

// Child entity's composite primary key 
@Embeddable 
public class InstanceNotifyEntityId implements Serializable { 
    Long eaihId; 
    Long userId; 
} 

// Child entity 
@Entity 
@Table(name="EIF_INST_NOTIFIED") 
public class InstanceNotifyEntity implements Serializable { 
    @AttributeOverrides({ 
     @AttributeOverride(name="userId", column = @Column(name="USER_ID")) 
     @AttributeOverride(name="eaihId", column = @Column(name="EAIH_ID")) 
    }) 
    @EmbeddedId 
    InstanceNotifyEntityId id; 

    @MapsId("eaihId") 
    @ManyToOne 
    InstanceEntity instance; 

    // ... 
} 

La entidad padre necesita un cambio: el atributo mappedByuserDetails debe ser "id.eaihId". Creo que eso es todo, pero no he usado entidades exactamente así antes. Puede haber perdido algo ... por favor publique si ve errores.

+0

Gracias, esto funciona en su mayor parte. Lamentablemente, no estoy utilizando jpa 2.0, por lo que la anotación @MapsId no está disponible. Esto funciona para inserciones al eliminar la relación en cascada del objeto userDetails de la entidad principal. Así que estoy obligado a insertar cada elemento hijo después de persistir el elemento principal, pero por el momento es viable. – broschb

+0

@broschb ¿Qué estás usando? –

+0

jpa 1.0 spec. Actualmente estoy obligado a usar jboss 4.2.3, mi entendimiento es que jpa 2.0 no funcionará en este servidor de aplicaciones, al menos no sin intercambiar un montón de bibliotecas. – broschb

0

También estaba enfrentando el mismo problema y seguí esta respuesta, pero no está guardando la entidad hijo con la entidad padre. Aquí están los cambios que hice y está funcionando bien. Hacer cambios a continuación -

// Child entity's composite primary key class 

public class InstanceNotifyEntityId implements Serializable { 

    @Column(name = "USER_ID") 
    Long userId; 

    @JoinColumn(name = "EAIH_ID") 
    @ManyToOne 
    InstanceEntity instance 
} 

// Child entity which contain composite primary key as a EmbeddedId, 
// no need to define any relationship here as we already define 
// the relationship in composite key class. 

@Entity 
@Table(name = "EIF_INST_NOTIFIED") 
public class InstanceNotifyEntity implements Serializable { 

    @EmbeddedId 
    InstanceNotifyEntityId id; 
} 


// Parent entity (parent entity mappedby should be your composite 
// key class instance.child class object which already have the 
// join column mapping with "EAID_ID") 

@Entity 
@Table(name = "EIF_INSTANCE_HDR") 
public class InstanceEntity implements Serializable { 

    @OneToMany(mappedBy = "id.instance,fetch=FetchType.EAGER, cascade = CascadeType.ALL) 
    private List<InstanceNotifyEntity> userDetails = new ArrayList<InstanceNotifyEntity>(); 
} 

Mientras se guarda la entidad matriz establece el objeto padre en la clave compuesta como id.setInstance(parent entire obj)

Cuestiones relacionadas