Estoy usando la relación javax.persistence.OneToMany en una relación padre-hijo. La identificación principal es nula, he leído todas las publicaciones relacionadas en Stackoverflow pero no tengo ni idea de lo que me estoy perdiendo. Todos los PK correspondientes se completan en las tablas principal y secundaria según la secuencia proporcionada, pero el FK se establece en nulo en la tabla secundaria
Clase de padres:
@Entity @Table(name = "DIVERSITY_TEMPLATE") public class DiversityTemplate implements Serializable { private static final long serialVersionUID = 1L; @Id @SequenceGenerator(name = "DIVERSITY_TEMPLATE_ID", sequenceName = "DIVERSITY_TEMPLATE_ID", allocationSize = 1) @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "DIVERSITY_TEMPLATE_ID") @Column(name = "DIVERSITY_TEMPLATE_ID") private Integer diversityTemplateId; @OneToMany(cascade = CascadeType.ALL, mappedBy = "diversityTemplate", fetch = FetchType.LAZY) private List<DiversityTemplateAttribute> attributes = new ArrayList<>();Clase infantil:
@Entity @Table(name = "DIVERSITY_TEMPLATE_ATTRIBUTE") @TypeName("DiversityTemplateAttribute") public class DiversityTemplateAttribute implements Serializable { private static final long serialVersionUID = 1L; @Id @SequenceGenerator(name = "DIVERSITY_TEMPLATE_ATTR_ID", sequenceName = "DIVERSITY_TEMPLATE_ATTR_ID", allocationSize = 1) @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "DIVERSITY_TEMPLATE_ATTR_ID") @Column(name = "DIVERSITY_TEMPLATE_ATTR_ID") private Integer diversityTemplateAttributeId; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "DIVERSITY_TEMPLATE_ID", nullable=false, referencedColumnName = "DIVERSITY_TEMPLATE_ID") private DiversityTemplate diversityTemplate;Clase de servicio:
diversityTemplateRepository.save(diversityTemplate);json de muestra
{ "diversityTemplateId": 0, "attributes": [{ "diversityTemplateId": 0, "diversityTemplateAttributeId": 0, }, { "diversityTemplateId": 0, "diversityTemplateAttributeId": 0, }] }Por favor recomiende.
Clase de padres:
@Entity @Table(name = "DIVERSITY_TEMPLATE") public class DiversityTemplate implements Serializable { private static final long serialVersionUID = 1L; @Id @SequenceGenerator(name = "DIVERSITY_TEMPLATE_ID", sequenceName = "DIVERSITY_TEMPLATE_ID", allocationSize = 1) @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "DIVERSITY_TEMPLATE_ID") @Column(name = "DIVERSITY_TEMPLATE_ID") private Integer diversityTemplateId; @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY) @JoinColumn(name = "DIVERSITY_TEMPLATE_ID") private List<DiversityTemplateAttribute> attributes = new ArrayList<>();Clase infantil:
@Entity @Table(name = "DIVERSITY_TEMPLATE_ATTRIBUTE") @TypeName("DiversityTemplateAttribute") public class DiversityTemplateAttribute implements Serializable { private static final long serialVersionUID = 1L; @Id @SequenceGenerator(name = "DIVERSITY_TEMPLATE_ATTR_ID", sequenceName = "DIVERSITY_TEMPLATE_ATTR_ID", allocationSize = 1) @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "DIVERSITY_TEMPLATE_ATTR_ID") @Column(name = "DIVERSITY_TEMPLATE_ATTR_ID") private Integer diversityTemplateAttributeId; @ManyToOne(fetch = FetchType.LAZY) private DiversityTemplate diversityTemplate;Clase de servicio:
diversityTemplateRepository.save(diversityTemplate);De esta manera, NO NECESITA HACER LA ENTRADA DE PADRE EN CADA NIÑO . lo hará por sí mismo. solo necesitas guardar a los padres, eso es todo.
Pasos rápidos lo que hice.
- Eliminado mappedBy de Padre.
- Se agregó la clave externa @JoinCollumn en Parent
- Se eliminó @JoinCollumn de Child.
Espero eso ayude.
Por lo general, las columnas FK vacías provienen de establecer solo un lado de la relación.
Imagino que tienes lo siguiente
DiversityTemplate diversityTemplate = ... diversityTemplate.getAttributes().add(...) ... diversityTemplateRepository.save(diversityTemplate); Esto es incorrecto porque DiversityTemplateAttribute no sabe sobre el padre, solo el padre sabe sobre sus hijos.
Resolver esto es fácil, debe establecer la referencia del padre en el hijo.
diversityTemplateAttribute.setDiversityTemplate(diversityTemplate); O puede poner esta lógica en un método dentro de DiversityTemplate que agrega automáticamente el atributo a la Lista + establece la referencia inversa.
@JsonManagedReference @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY) @JoinColumn(name = "DIVERSITY_TEMPLATE_ID") private List<DiversityTemplateAttribute> attributes = new ArrayList<>(); . . . . @JsonBackRefrence @ManyToOne(fetch = FetchType.LAZY) private DiversityTemplate diversityTemplate;estos JsonManagedReference y JsonBackReference son proporcionados por la biblioteca jackson para que JPA sepa en qué clase debe serializar y en cuál no... para que podamos evitar la recursión infinita... ¡más sobre esto aquí !