【问题标题】:JPA Hibernate Annotation IssueJPA Hibernate 注释问题
【发布时间】:2021-03-22 01:43:17
【问题描述】:

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

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

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

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;
}

【问题讨论】:

    标签: java hibernate jpa jdbc entity


    【解决方案1】:

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

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

    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 注释中声明父对象名称,因为它会为该外键创建一个列。

    【讨论】:

    • 需要我做一些事务性的事情吗?保存时,我现在使用此设置看到以下错误 - HHH000010:在批处理发布时它仍然包含 JDBC 语句:org.hibernate.TransientObjectException:对象引用未保存的瞬态实例 - 在刷新之前保存瞬态实例:com. usaa.pc.property.downdetector.model.Project
    • 如果您遇到这样的错误,请检查您是否已经为新创建的对象(即 Project)传递了一个“ID”。对于新条目,它应该为 null。
    • 我需要 CascadeType.ALL 所有的集合——不过,这行得通。
    【解决方案2】:

    您应该将每个连接列标记为 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),因此,在您的实体上,您应该将数据类型标记为您所引用的实体,而不是一个集合。

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

    【讨论】:

    • 需要我做一些事务性的事情吗?保存时,我现在使用此设置看到以下错误 - HHH000010:在批处理发布时它仍然包含 JDBC 语句:org.hibernate.TransientObjectException:对象引用未保存的瞬态实例 - 在刷新之前保存瞬态实例:com. usaa.pc.property.downdetector.model.Project
    • 我需要 CascadeType.ALL 所有的集合——不过,这行得通。
    • 两个答案都是正确的,他只是帮助跟进:(
    猜你喜欢
    • 2013-08-20
    • 2011-09-29
    • 2011-12-07
    • 1970-01-01
    • 2010-09-23
    • 2020-02-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多