如何使用带有 JoinColumn 的 JPA 实体的全参数构造函数?

时间:2021-03-06 10:36:08

标签: java spring postgresql spring-boot jpa

我正在开发一个 Spring Boot 应用程序(REST 存储库、JPA、PostgreSQL)来托管项目的 REST API。用户可以选择要种植的植物种类。这是存储与用户关联的植物数据的实体代码的一部分。

@Data
@Entity
@NoArgsConstructor
@Table(name = "plant")
public class Plant {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "plant_id")
    private UUID plantID;

    @ManyToOne(cascade = CascadeType.MERGE, fetch = FetchType.EAGER)
    @JoinColumn(name = "user_id")
    private User user;

    @ManyToOne(cascade = CascadeType.MERGE, fetch = FetchType.EAGER)
    @JoinColumn(name = "species_id")
    private PlantSpecies species;

    @Column(name = "date_of_planting")
    private Date dateOfPlanting;
}

我正在尝试创建一个 API,用于创建 Plant 的新实例并将其保存到我的数据库中。理想情况下,请求应该给我一个 userID 和一个 speciesID,我应该能够用这样的东西构造一个新的 Plant

    // PROBLEM HERE
    public Plant(String userID, String speciesID) {
        this.user = userID;
        this.species = speciesID;
        this.dateOfPlanting = new Date();
    }

我的数据库中的表只存储了各自的外键(字符串),所以如果我需要插入一条新记录,我应该可以简单地存储字符串,对吗?但是在实体中,数据不是以字符串形式存储的,它们是这些类的对象。在这种情况下,构造函数代码显然是错误的。我知道我的逻辑有缺陷,但我无法确定在哪里以及如何修复它。

我可以选择查询 User 和 PlantSpecies 表以获取记录,并将其传递到此构造函数中,这将解决我的错误,但我觉得这是错误的。我不应该获取整个记录来存储我已经拥有的 ID。我很感激这方面的任何帮助,提前致谢!

1 个答案:

答案 0 :(得分:0)

如果您必须在使用时使用 JPA,则必须首先从数据库中获取用户,然后在 Plant 实体的​​构造函数中设置此用户对象。如果您必须将一个实体对象与另一个实体对象相关联,这就是 JPA 的工作方式。如果您不想先获取用户并将该用户对象与 Plant 对象相关联,那么您必须删除关系 @ManyToOne 注释并将其存储为字符串类型或整数类型的普通数据列,无论适合你的场景。需要注意的一件事是,在将此 id 分配给植物对象之前,指定的用户 id 确实存在于您的数据库中