【问题标题】:Posting just the id of unidirectional many to one relationship只发布单向多对一关系的 id
【发布时间】:2019-10-22 15:06:38
【问题描述】:

我正在提交一个 POST 请求 (JSON) 来创建一个新的 Person 实例,并且每个 Person 都必须有一个与之关联的状态。有一个预先填充的状态表,它具有有限数量的状态。只是在这里提交状态的实体 id 是最好的方法吗?

目前,我在请求中只提交了 Status 实体的 id,但这意味着使用该 id 从数据库中加载一个 Status 并将其添加到临时 Person 中,然后再将其预先持久化以满足 JPA/DB 约束,但是这是低效的。

请求正文(为简洁起见被截断)解组到 PersonDTO:

{
    "name" : "Dave",
    "statusId" : "1",
    ::
}

状态实体

@Entity
public class Status {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    private Long id;

    @Column
    private String status;
}

人物实体

@Entity
public class Person {

   @Id
   @GeneratedValue(strategy = GenerationType.SEQUENCE)
   private Long id;

    @ManyToOne(optional = false)
    @JoinColumn(name = "status_id")
    private Status status;
    ::

最好的方法是在 JSON 请求中实际提交状态对象,这样我就不必对状态 ID 执行任何类型的查找了吗?

{
    "name" : "Dave",
    "status" : {
      "id" : 1
      "status" : "AVAILABLE"
    },
    ::
}

我很感激我可以在启动时将状态预加载到单例中,以便可以访问它们或缓存使用 id 返回状态的服务类方法,但我想知道这里最好的方法是什么,因为如果我使用的是本机SQL 我可以将 Person 插入到带有状态 ID 的数据库中,而不事先执行任何状态查找。

【问题讨论】:

    标签: java hibernate rest spring-boot jpa


    【解决方案1】:

    1) 一旦你开始使用 Native SQL,你就会开始在越来越多的地方使用它。最终,您将失去 JPA 为您提供的数据库提供者独立性。我不是说它是 100% 坏的,我只是说..

    2) 您可以为Status 应用二级缓存,因为它似乎是一种字典表:

    @Entity
    @Cacheable
    

    3) 如果您不希望对状态对象本身进行任何更改,则不应使用 findById 加载它,该 findById 会进入数据库,而是使用 getOne 而不是只创建一个引用,在您的情况下应该足够了。

    【讨论】:

    • 感谢 Maciej,不知道 getOne,但这正是我想要的。
    猜你喜欢
    • 2019-05-13
    • 1970-01-01
    • 2015-05-19
    • 2013-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多