JPA Hibernate 注释问题

JPA Hibernate Annotation Issue

我正在建模三个实体,但相关注释存在问题。我基本上有一个 class,我打算返回给调用者,一个项目的嵌套列表,项目可以包含一个端点的嵌套列表。是顶层has-a一对多,那么嵌套的一对多有两个一对多。

我玩过 @JoinColumn 注释,我试图将 @ManyToOne 放在 OneToMany 的另一边(但它不喜欢它是一个 Long..) .我只是相当新,不确定如何做到这一点。我认为 mappedById 是解决方案,但我不确定。

主要问题:这段代码允许我“保存”到数据库,但在检索时,DownDetectorPackage 中的项目列表是空的。

A CascadeType.ALL 抛出我不完全理解的引用完整性错误。

@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Builder                                                                               
public class DownDetectorPackage {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;

@OneToMany(mappedBy="id",fetch = FetchType.EAGER)
private List<Project> projects;

@Temporal(TemporalType.DATE)
private Date dateJobsLastRan;

@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Project{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;
    private String projectName;
    @OneToMany(mappedBy="id")
    private List<Service> externalDependencies;
    @OneToMany(mappedBy="id")
    private List<Service> endpoints;
}

@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Service {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String url;
    private Boolean endpointIsUp;
    private String serviceName;
}

您应该将每个连接列标记为 JoinColumn,表示来自其他实体的引用列。然后,您应该说出哪种关系类型正在使用此列。

public class Project {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    private String projectName;

    @JoinColumn(referencedColumnName = "id")
    @OneToMany(fetch = FetchType.LAZY)
    private ExternalDependencyEntity externalDependencies;

    @JoinColumn(referencedColumnName = "id")
    @OneToMany(fetch = FetchType.LAZY)
    private EndpointEntity endpoints;
}

最后,请注意,在关系数据库中,每个 fk 列只能取 1 个值(引用实体 ID 的 pk),因此,在您的实体上,您应该将数据类型标记为您所引用的实体,并且没有作为一个集合。

我认为这可以解决您的问题。

您应该使用@JoinColumn 而不是mappedBy。当您在另一个 class 中也使用了 @ManyToOne 时,可以使用 MappedBy,而您还没有。

所以你的最终 class 应该看起来像这样(这也适用于你提到的其他 classes):

public class DownDetectorPackage {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;

@JoinColumn(name = "downDetectorPackageId")
@OneToMany(fetch = FetchType.EAGER)
private List<Project> projects;

@Temporal(TemporalType.DATE)
private Date dateJobsLastRan;

此外,请记住在@JoinColumn 注释中声明父对象名称,因为它会为该外键创建一个列。