![](/img/trans.png)
[英]Spring Boot with hibernate: Creating Composite Key and Many-to-many relations
[英]Spring hibernate : Persisting an entity with many-to-many relation and a composite key
我有两个通过多对多关系链接的实体,该关系的所有者具有复合主键,该主键是用@Emebbedable注释的类。 这是实体类:
Reservation.java:
@Entity
@NamedQuery(name="Reservation.findAll", query="SELECT r FROM Reservation r")
public class Reservation implements Serializable {
private static final long serialVersionUID = 1L;
@EmbeddedId
private ReservationPK id;
private int actif;
private String commentaire;
@Column(name="date_creation")
private Timestamp dateCreation;
@Column(name="date_liberation")
private Timestamp dateLiberation;
private int indice;
private String libelle;
private String nom;
//bi-directional many-to-many association to Composant
@LazyCollection(LazyCollectionOption.FALSE)
@ManyToMany
@JoinTable(
name="resa_comp"
, joinColumns={
@JoinColumn(name="id_env", referencedColumnName="id_env"),
@JoinColumn(name="id_reserv", referencedColumnName="id_reserv")
}
, inverseJoinColumns={
@JoinColumn(name="id_comp")
}
)
@JsonBackReference
private List<Composant> composants;
// getters and setters ...
ReservationPK.java:
@Embeddable
public class ReservationPK implements Serializable {
//default serial version id, required for serializable classes.
private static final long serialVersionUID = 1L;
@Column(name="id_reserv")
@GeneratedValue(strategy=GenerationType.IDENTITY)
private int idReserv;
@Column(name="id_env", insertable=false, updatable=false)
private int idEnv;
public ReservationPK() {
}
public int getIdReserv() {
return this.idReserv;
}
public void setIdReserv(int idReserv) {
this.idReserv = idReserv;
}
public int getIdEnv() {
return this.idEnv;
}
public void setIdEnv(int idEnv) {
this.idEnv = idEnv;
}
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (!(other instanceof ReservationPK)) {
return false;
}
ReservationPK castOther = (ReservationPK)other;
return
(this.idReserv == castOther.idReserv)
&& (this.idEnv == castOther.idEnv);
}
public int hashCode() {
final int prime = 31;
int hash = 17;
hash = hash * prime + this.idReserv;
hash = hash * prime + this.idEnv;
return hash;
}
Composant.java:
@Entity
@NamedQuery(name="Composant.findAll", query="SELECT c FROM Composant c")
public class Composant implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="id_comp")
private int idComp;
@Size(max=250)
@Column(name="attribut_1")
private String attribut1;
@Size(max=250)
@Column(name="attribut_2")
private String attribut2;
@Size(max=250)
@Column(name="attribut_3")
private String attribut3;
@Size(max=250)
@Column(name="attribut_4")
private String attribut4;
@Size(max=250)
@Column(name="attribut_5")
private String attribut5;
//bi-directional many-to-many association to Reservation
@LazyCollection(LazyCollectionOption.FALSE)
@ManyToMany(mappedBy="composants")
@JsonManagedReference
private List<Reservation> reservations;
当我尝试使用getCurrentSession.save()
保留包含Composant列表的Reservation实例时,出现以下错误:
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (`scott`.`resa_comp`, CONSTRAINT `fk_reservation_has_composant_reservation1` FOREIGN KEY (`id_reserv`, `id_env`) REFERENCES `reservation` (`id_reserv`, `id_env`) ON DELETE NO ACTION ON UPDATE N)
我可以在日志文件中看到hibernate尝试使用id_reserv = 0将记录插入关系表中,有什么方法可以使hibernate在将记录插入关系表中时使用正确的ID?
我试图通过尝试先保存保留对象,然后再链接composant列表,然后更新保留,来修改位于服务层中的保存方法,但是我遇到了同样的错误。 供参考的是我的DAO和服务层的save方法:
saveDao:
@Override
public Reservation save(Reservation r) {
// TODO Auto-generated method stub
ReservationPK idResaPK = (ReservationPK) this.sessionFactory.getCurrentSession().save(r);
System.out.println("id resa saved = "+idResaPK.getIdReserv());
return this.getById(idResaPK);
}
saveService:
@Override
public Reservation save(Reservation r) {
// TODO Auto-generated method stub
if(r.getComposants().isEmpty()) {
logger.info("you are here ! empty");
return this.resDao.save(r);
}
else {
logger.info("you are here ! full");
List<Composant> listComp = new ArrayList<Composant>();
listComp.addAll(r.getComposants());
for (Composant composant : r.getComposants()) {
//listComp.add(composant);
composant.setReservations(new ArrayList<Reservation>());
}
r.setComposants(new ArrayList<Composant>());
if( r.getComposants() != null) {
for (Composant comp : r.getComposants()) {
logger.info("you are here jsdhjshqdlkhdjh :"+comp.getNom());
}
}
Reservation resaSaved = this.resDao.save(r);
logger.info("done saving : "+resaSaved.getId().getIdReserv());
resaSaved.setComposants(listComp);
ArrayList<Reservation> resaList = new ArrayList<Reservation>();
resaList.add(r);
for (Composant compo : listComp) {
compo.setReservations(resaList);
}
this.resDao.update(resaSaved);
logger.info("done updating");
return r;
}
}
提前致谢。
在将原始数据类型用作主键的地方,将标有@Id注释的属性的数据类型更改为原始包装器类。 保存新实体时,id属性的值为零,而使用原始包装器时,值为NULL。 在保留新实体时,id值应为null,而此处为0。
进行以下更改:
//ReservationPK class
@Column(name="id_reserv")
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer idReserv;//instead of int
@Column(name="id_env", insertable=false, updatable=false)
private Integer idEnv;//instead of int
//Composant class
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="id_comp")
private Integer idComp; //instead of int
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.