Java Spring hibernate:持久化具有多对多关系和复合键的实体
我有两个由多对多关系链接的实体,关系的所有者有一个复合主键,它是一个用@emebbeable注释的类。 以下是实体类: Reservation.java:Java Spring hibernate:持久化具有多对多关系和复合键的实体,java,spring,hibernate,jpa,Java,Spring,Hibernate,Jpa,我有两个由多对多关系链接的实体,关系的所有者有一个复合主键,它是一个用@emebbeable注释的类。 以下是实体类: Reservation.java: @Entity @NamedQuery(name="Reservation.findAll", query="SELECT r FROM Reservation r") public class Reservation implements Serializable { private static final long serialVers
@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 ...
Composant.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;
}
@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;
@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);
}
@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;
}
}
我可以在日志文件中看到,hibernate正在尝试使用id\u reserv=0将记录插入关系表中
在将记录插入关系表时,有没有办法让hibernate使用正确的id
我试图修改位于服务层的save方法,方法是在链接组件列表之前先保存Reservation对象,然后更新Reservation,但我得到了相同的错误。
以下是我的DAO和服务层的保存方法供参考:
saveDao:
@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;
}
@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;
@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);
}
@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;
}
}
saveService:
@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;
}
@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;
@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);
}
@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;
}
}
@覆盖
公共预订保存(预订r){
//TODO自动生成的方法存根
if(r.getComposants().isEmpty()){
logger.info(“你在这里!空”);
返回此.resDao.save(r);
}
否则{
logger.info(“您在这里!已满”);
List listComp=new ArrayList();
listComp.addAll(r.getcomponents());
for(Composant Composant:r.getComposants()){
//列表组件添加(组件);
setReservations(newarraylist());
}
r、 setComponents(新的ArrayList());
if(r.getComposants()!=null){
对于(组件组件:r.getComposants()){
info(“您在这里是jsdhjshqdlkhdjh:+comp.getNom());
}
}
resaSaved=this.resDao.save(r);
logger.info(“完成保存:+resaSaved.getId().getIdReserv());
重新保存。设置组件(列表组件);
ArrayList resaList=新的ArrayList();
重新分配清单。添加(r);
用于(组件组件:列表组件){
组件设置预订(转售列表);
}
this.resDao.update(已保存);
logger.info(“完成更新”);
返回r;
}
}
提前感谢。将标有@Id注释的属性的数据类型更改为使用基本数据类型作为主键的基本包装类。保存新实体时,id属性的值为零,而使用原始包装时,该值为空。在持久化新实体时,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
谢谢你的回答,我试着把ID改成整数,但没能解决我的问题。我的实际问题是hibernate无法获取插入的保留的id,以便在关系表resa_comp中插入记录,因此我得到了一个约束冲突,因为它检测到resa_comp表中的id_reserv列不能为null或0。