Estoy usando Hibernate con anotaciones (en primavera), y tengo un objeto que tiene una relación ordenada, muchos a uno que un objeto secundario que tiene una clave primaria compuesta, uno de cuyos componentes es una clave externa. a la identificación del objeto principal.@OneToMany y teclas primarias compuestas?
La estructura es como la siguiente:
+=============+ +================+
| ParentObj | | ObjectChild |
+-------------+ 1 0..* +----------------+
| id (pk) |-----------------| parentId |
| ... | | name |
+=============+ | pos |
| ... |
+================+
He probado una variedad de combinaciones de anotaciones, ninguna de las cuales parece funcionar. Esto es lo más cerca que he sido capaz de llegar a:
@Entity
public class ParentObject {
@Column(nullable=false, updatable=false)
@Id @GeneratedValue(generator="...")
private String id;
@OneToMany(mappedBy="parent", fetch=FetchType.EAGER, cascade={CascadeType.ALL})
@IndexColumn(name = "pos", base=0)
private List<ObjectChild> attrs;
...
}
@Entity
public class ChildObject {
@Embeddable
public static class Pk implements Serializable {
@Column(nullable=false, updatable=false)
private String parentId;
@Column(nullable=false, updatable=false)
private String name;
@Column(nullable=false, updatable=false)
private int pos;
@Override
public String toString() {
return new Formatter().format("%s.%s[%d]", parentId, name, pos).toString();
}
...
}
@EmbeddedId
private Pk pk;
@ManyToOne
@JoinColumn(name="parentId")
private ParentObject parent;
...
}
llegué a este después de un largo combate de la experimentación en la que la mayoría de mis otros intentos produjeron entidades que hibernación ni siquiera podía cargar por diversas razones .
ACTUALIZACIÓN: Gracias a todos por los comentarios; He hecho algun progreso. He realizado algunos ajustes y creo que está más cerca (he actualizado el código anterior). Ahora, sin embargo, el problema está en insertar. El objeto principal parece guardar bien, pero los objetos secundarios no se guardan, y lo que he podido determinar es que hibernate no está llenando la parte parentId de la clave primaria (compuesta) de los objetos hijo, entonces I ' m conseguir un error no es exclusivo:
org.hibernate.NonUniqueObjectException:
a different object with the same identifier value was already associated
with the session: [org.kpruden.ObjectChild#null.attr1[0]]
estoy poblando las name
y pos
atributos en mi propio código, pero por supuesto no sé el ID de los padres, ya que no se ha guardado todavía. ¿Alguna idea sobre cómo convencer a hibernate para completar esto?
Gracias!
Lo mejor de la suerte. Un proyecto en el que estaba tenía que abandonar por completo las claves compuestas a favor de las claves sintéticas debido al poco apoyo de Hibernate. –
La excepción puede ser causada por el uso de List <>. Debe usar Set <> para evitar la duplicación de clave usando hashCode y es igual a la definición. Hibernate trata dos elementos "lógicamente idénticos" en una lista para que sean dos elementos, y luego provocó la excepción. – Popeye