Q1. ¿Cómo podemos modelar una relación ternaria usando Hibernate? Por ejemplo, ¿cómo podemos modelar la relación ternaria presentada aquí usando Hibernate (o JPA)? (...)
Me gustaría remodelar la asociación con una clase de entidad intermedia (y esa es la manera recomendada con Hibernate). Aplicado a tu ejemplo:
@Entity
public class Sale {
@Embeddable
public static class Pk implements Serializable {
@Column(nullable = false, updatable = false)
private Long soldById;
@Column(nullable = false, updatable = false)
private Long buyerId;
@Column(nullable = false, updatable = false)
private Long productId;
public Pk() {}
public Pk(Long soldById, Long buyerId, Long productId) { ... }
// getters, setters, equals, hashCode
}
@EmbeddedId
private Pk pk;
@ManyToOne
@JoinColumn(name = "SOLDBYID", insertable = false, updatable = false)
private SaleAssistant soldBy;
@ManyToOne
@JoinColumn(name = "BUYERID", insertable = false, updatable = false)
private Customer buyer;
@ManyToOne
@JoinColumn(name = "PRODUCTID", insertable = false, updatable = false)
private Product product;
// getters, setters, equals, hashCode
}
Q1.1. ¿Cómo podemos modelar esta variación, en la que cada artículo de venta podría tener muchos productos?
No utilizaría una clave primaria compuesta aquí e introduciría un PK para la entidad Sale
.
Q2. En general, ¿cómo podemos modelar las relaciones n-ary, n> = 3 con Hibernate?
Creo que mi respuesta a Q1. cubre esto. Si no es así, por favor aclare.
Actualización: Contestación de los comentarios de la OP
(...) los campos del pk no se están pobladas y como consecuencia no puedo guardar elementos de venta en la base de datos. ¿Debería usar setters como este para la clase Sale? public void setBuyer (Customer cust) {this.buyer = cust; this.pk.buyerId = cust.getId(); }
Es necesario crear una nueva Pk
(quité los constructores de mi respuesta original de la concisión) y configurarlo en el elemento Sale
. Me gustaría hacer algo como esto:
Sale sale = new Sale();
Pk pk = new Pk(saleAssistant.getId(), customer.getId(), product.getId());
sale.setPk(pk);
sale.setSoldBy(saleAssistant);
sale.setBuyer(customer);
sale.setProduct(product);
...
Y entonces se mantienen, el sale
.
Además, en las anotaciones de JoinColumn, ¿a qué columna se refieren los campos de "nombre"? ¿Los pks de las relaciones objetivo o los propios nombres de columna de la tabla de ventas?
Para las columnas de los atributos de los Pk
(es decir, propios nombres de las columnas de la tabla venta) compuestos, queremos que se obtienen PK y el FK limitaciones.
Gracias por la respuesta. Pero me encuentro con un problema cuando uso esto: los campos del pk no se están llenando y, como resultado, no puedo guardar elementos de Venta en el DB. ¿Debo usar adaptadores como este para la clase Venta? public void setBuyer (Customer cust) { this.buyer = cust; this.pk.buyerId = cust.getId(); } Además, en las anotaciones de JoinColumn, ¿a qué columna se refieren los campos de "nombre"? ¿Los pks de las relaciones objetivo o los propios nombres de columna de la tabla de ventas? – Behrang