我使用 Springboot 和 MySQL 来制作 API, 我目前遇到一个问题,在互联网上找不到任何答案:
问题出在我下面的关联表“EtapeRecette.java”中,我尝试使用 Lombok 初始化 getter 和 setter,但是当我使用 @Data 时,我没有收到任何错误,但是当我使用 RecetteRepository 的 findAll() 时,我得到一个数组“etapes”为空,但是如果我手动在“EtapeRecette.java”中设置 getter 和 setter,它工作得很好,如果我使用 @Getters 和 @Setters,同样如此,有什么原因 @Data 不起作用吗?
我有3张桌子:
Recette.java
package org.microferme.charme.model;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import jakarta.persistence.*;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.sql.Timestamp;
import java.util.Date;
import java.util.Set;
@Data
@NoArgsConstructor
@Entity
@Table(name="Recette")
public class Recette {
@Id
private String id;
@Column(name = "nom")
private String nom;
@Column(name = "nb_personne")
private int nbPersonne;
@Column(name = "prix_par_personne")
private float prixParPersonne;
@OneToMany(mappedBy = "recette", cascade = CascadeType.ALL, orphanRemoval = true)
@JsonIgnoreProperties("recette")
private Set<MediaRecette> medias;
@OneToMany(mappedBy = "recette", cascade = CascadeType.ALL, orphanRemoval = true)
@JsonIgnoreProperties("recette")
private Set<StockUtile> ingredients;
@OneToMany(mappedBy = "recette", cascade = CascadeType.ALL, orphanRemoval = true)
@JsonIgnoreProperties("recette")
private Set<EtapeRecette> etapes;
public Recette(String nom, int nbPersonne, float prixParPersonne) {
//Si l'id n'est pas spécifié on prend la timestamp actuelle
Date date = new Date();
this.id = String.valueOf(new Timestamp(date.getTime()).getTime());
this.nom = nom;
this.nbPersonne = nbPersonne;
this.prixParPersonne = prixParPersonne;
}
public void addMedia(MediaRecette media) {
this.medias.add(media);
}
public void addIngredient(StockUtile ingredient) {
this.ingredients.add(ingredient);
}
public void addEtape(EtapeRecette etapeRecette) {
this.etapes.add(etapeRecette);
}
}
Etape.java
package org.microferme.charme.model;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import jakarta.persistence.*;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
import java.util.Set;
@Data
@Entity
@Table(name = "Etape")
public class Etape {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column(name = "ordre")
private float ordre;
@Column(name = "duree")
private float duree;
@Column(name = "description")
private String description;
@ManyToOne
private Ustensile ustensile;
public Etape() {
}
public Etape(float ordre, float duree, String description, Ustensile ustensile) {
this.ordre = ordre;
this.duree = duree;
this.description = description;
this.ustensile = ustensile;
}
}
EtapeRecette 这是 Recette 和 Etape 之间的关联表,以便具有多对多关系
package org.microferme.charme.model;
import jakarta.persistence.*;
import lombok.Data;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.microferme.charme.model.embeddable.EtapeRecetteId;
@Entity
@Data
@Table(name = "EtapeRecette")
public class EtapeRecette {
@EmbeddedId
private EtapeRecetteId id;
@ManyToOne(cascade = CascadeType.ALL)
@MapsId("recetteId")
private Recette recette;
@ManyToOne(cascade = CascadeType.ALL)
@MapsId("etapeId")
private Etape etape;
public EtapeRecette() {
}
public EtapeRecette(Recette recette, Etape etape) {
this.id = new EtapeRecetteId(recette.getId(), etape.getId());
this.recette = recette;
this.etape = etape;
}
}
不同之处在于,
@Data
不仅生成getters
和setters
,还生成equals
和hashCode
方法。这些方法的默认实现不能很好地处理一对多和多对一等 Hibernate 关系。如果您使用 @Getter
@Setter
和 @EqualsAndHashCode(onlyExplicitlyIncluded = true)
的组合并将 @EqualsAndHashCode.Include
添加到 ID 字段,效果会更好。像这样:
@Entity
@Getter
@Setter
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
@Table(name="Recette")
public class Recette {
@Id
@EqualsAndHashCode.Include
private String id;
@OneToMany(mappedBy = "recette", cascade = CascadeType.ALL, orphanRemoval = true)
@JsonIgnoreProperties("recette")
private Set<EtapeRecette> etapes;
基于:https://thorben-janssen.com/lombok-hibernate-how-to-avoid-common-pitfalls/
它们似乎是您的 @OneToMany 映射的复制粘贴问题