【问题标题】:SpringBoot: Is this correct way to save a new entry which has ManyToOne relationship?Spring Boot:这是保存具有 ManyToOne 关系的新条目的正确方法吗?
【发布时间】:2016-06-16 22:54:07
【问题描述】:

我有两个实体 PersonVisit

PersonVisit 具有 OneToMany 关系。 我想知道是否要保存一个新的访问条目,以及使用 RestController。我的方法正确吗?还是有其他更高效的方法?

所以我有以下控制器,它从 RequestBody 中获取 VisitModel,这样调用它是否正确?

VisitModel 具有人员 ID,以及访问实体所需的属性。我使用 person 的 ID 在 personRepository 中查找相关的 Person 条目,然后将其发布到一个新的 Visit 实例,然后使用 visitRepository 保存它。

@RequestMapping(value="", method=RequestMethod.POST)
public String checkIn(@RequestBody VisitModel visit) {

    Person person = personRepository.findById(visit.personId);

    Visit newVisit = new Visit(visit.getCheckIn, person);
    visitRepository.save(newVisit);

    return "success";
}

访问实体如下所示

@Entity
public class Visit {

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

    @JsonProperty("check_in")
    private Date checkIn;

    @JsonProperty("check_out")
    private Date checkOut;

    @ManyToOne
    @JoinColumn(name="personId")
    private Person person;

    public Visit(Date checkIn, Person person) {
        this.checkIn = checkIn;
        this.person = person;
    }

    public Date getCheckIn() {
        return checkIn;
    }

    public void setCheckIn(Date checkIn) {
        this.checkIn = checkIn;
    }

    public Date getCheckOut() {
        return checkOut;
    }

    public void setCheckOut(Date checkOut) {
        this.checkOut = checkOut;
    }

    public Person getPerson() {
        return person;
    }

}

我想知道下面的做法是否正确。还是有其他更好的方法?

【问题讨论】:

  • 我可以看到的一个优化不是使用存储库方法获取人员对象,而是可以使用 new 运算符创建人员对象并填充 ID 字段并使用它。这将保存数据库命中以获取人员对象。
  • @MadhusudanaReddySunnapu 你的意思是关注new Person(personId); ?
  • 是的。你觉得这有什么问题吗?

标签: spring hibernate jpa spring-boot


【解决方案1】:

当然,您无需从数据库中获取Person 即可将其与Visit 关联。因为,您只需要将 Person 中的 id 保存在外键列 personId 中。

如果你使用 JPA EntityManager

  Person person = entityManager.getReference(Person.class, visit.personId);

对于休眠Session

  Person person = session.load(Person.class, visit.personId);

这个方法只是创建一个代理,不做任何数据库请求。

对于休眠 Session,我按照 @MadhusudanaReddySunnapu 的建议使用了 new Person(personId)。一切正常。

What is the difference between EntityManager.find() and EntityManger.getReference()?

Hibernate: Difference between session.get and session.load

【讨论】:

  • 使用new Person(personId)时,它没有从数据库中加载条目。然而,它使用 EntityManager 运行良好。使用Session,我无法使用@Autowired 注入它。如何获取会话实例?
  • @starcorn 如果您使用EntityManager — 使用getReference()new Person(personId)(当然,如果它有效)。不要混合使用EntityManagerSession。回答你的问题:你可以从EntityManagerSession session = entityManager.unwrap(Session.class);创建一个会话
【解决方案2】:

是的,在我看来,这是映射bidirectional 关系的标准方式。编辑:personId 列指向Person 实体的“id”字段。例如:

@Id
private Long id;

更新:1:VisitModel 是一个“DTO”或数据传输对象。任何单独的包装都可以。您可以考虑将它们放入单独的 jar 中,以便使用您的 API(使用 java)的任何人都可以在调用之前使用 jar 来创建数据。 2)据我所知,您保存它的方式很好。

【讨论】:

  • 那么你会把VisitModel放在什么包里。现在我有实体和存储库类,包含在域包中。但是 VisitModel 不适合那里。
  • 所以要保存访问的条目,你也会像我一样做吗?首先使用personId 查找Person,然后将其发送给一个新的Visit 实例?
  • 谢谢。不知道 DTO 是它的概念名称 :)
  • 不明白,为什么会这样:personId列在你的Person实体中也应该命名为personId,如果它被命名了
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-08-17
  • 1970-01-01
  • 2017-07-28
  • 2021-06-30
  • 2018-10-31
  • 1970-01-01
  • 2018-04-04
相关资源
最近更新 更多