Tenemos un modelo en el que tenemos una entidad (que llamaremos padre) relacionada con otra mediante un @OneToMany (que llamaremos hijos). Los hijos tienen una clave primaria compuesta, en la que aparece la clave primaria del padre (clave foránea).
Podemos crear el padre y los hijos mediante un solo persist, vamos un ejemplo:
Tenemos la entidad Documento (el padre) que dentro puede contener una lista de Firmantes (los hijos) relación @OneToMany:
public class Documento implements java.io.Serializable { private List<Firmante> firmantes = new ArrayList<Firmante>(); @OneToMany(fetch = FetchType.LAZY, mappedBy = "documento", cascade = CascadeType.ALL) public List<Firmante> getFirmantes() { return this.firmantes; } public void setFirmantes(List<Firmante> firmantes) { this.firmantes = firmantes; } }
Para no tener que hacer un persist explícito del objeto _Firmante_, en la relación @OneToMany he establecido un CascadeType.ALL. La entidad Firmante tiene una clave primaría compuesta por el par documento, identificador del firmante.
@Entity @Table(name = "GDOC_FIRMANTES_DOC", schema="GESPERDOC") public class Firmante implements java.io.Serializable { private Firmanted id; private Documento documento; public Firmante() { } @EmbeddedId @AttributeOverrides({ @AttributeOverride(name = "doc", column = @Column(name = "GFD_DOC", nullable = false, precision = 10, scale = 0)), @AttributeOverride(name = "identificador", column = @Column(name = "GFD_IDENTIFICADOR", nullable = false, length = 8))}) @NotNull public FirmanteId getId() { return this.id; } public void setId(FirmanteId id) { this.id = id; } @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "GFD_DOC", nullable = false, insertable = false, updatable = false) @NotNull public Documento getDocumento() { return this.documento; } ... }
Cuando creo una instancia del firmante, como el documento aún no ha sido persistido no existe el ID y por lo tanto no lo establece en FirmanteId. Además, aunque le asocio la entidad el documento, como dicha relación tiene las propiedades insertable y updatable a false (pues si no fallaría por propiedad duplicada), cuando se realiza el persist de todo, aunque primero se haga el del documento no le asigna su ID al firmante. Para solventar dicho problema en la clase Firmante he hecho uso del listener PrePersist:
@PrePersist public void prepersist() { if (getDocumento() != null) { getId().setDoc( getDocumento().getId() ); } }
— Juan Ferrer Martínez 2017/02/15 18:13