当前位置: 首页 > 知识库问答 >
问题:

使用一对一关系同时保存两个实体

胡飞鹏
2023-03-14

我已经试着解决这件事很长一段时间了,但我什么也没得到。我一直在试图保存一个实体,该实体拥有对另一个实体的引用。

用户通过填写表单创建一个place实体,然后按save保存该实体。它应该自动在“places”和“place\u url”表中创建新行。下面是我正在加载到应用程序中的SQL文件的链接:https://pastebin.com/x8Gvk7ub

母实体:

@Entity
@Table(name="places")
public class Place {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name="id", nullable=false, updatable=false)
    private Long id;

    @Column(name="userId")
    private Long userId;

    @Column(name="name", nullable=false, unique=true)
    private String name;

    @Column(name="address", nullable=false)
    private String address;

    @Column(name="largeDescription", nullable=false)
    private String largeDescription;

    @Column(name="smallDescription", nullable=false)
    private String smallDescription;

    @OneToOne(fetch=FetchType.LAZY, cascade=CascadeType.ALL)
    @JoinColumn(name="id")
    private PlaceUrl placeUrl;

    @OneToMany(fetch=FetchType.LAZY, cascade=CascadeType.ALL)
    @JoinColumn(name="id")
    private List<Booking> bookings;

    getters and setters...
}

子实体:

@Entity
@Table(name="placeUrls")
public class PlaceUrl {

    @Id
    @Column(name="id", nullable=false, updatable=false)
    private Long id;

    @Column(name="placeId", nullable=false, updatable=false)
    private Long placeId;

    @Column(name="url", nullable=false, updatable=true, unique=true)
    private String url;

    @OneToOne
    @JoinColumn(name="id", referencedColumnName="placeId")
    private Place place;

    getters and setters...
}

控制器:

@PostMapping("/place/add")
public String addPlace(@ModelAttribute Place place, @AuthenticationPrincipal UserDetails currentUser) {
     User user = userRepository.findUserByUsername(currentUser.getUsername());
     place.setUserId(user.getId());
     placeRepository.save(place);
     return "redirect:/places";
}

Hibernate命名在application.properties中设置为implicitic-策略

更新:

地点实体:

@OneToOne(fetch=FetchType.LAZY, cascade=CascadeType.ALL, mappedBy="place")
private PlaceUrl placeUrl;

PlaceUrl实体:

Removed the placeId column, placeId variable and it's getters and setters.

@OneToOne(fetch=FetchType.LAZY)
@JoinColumn(name="placeId")
private Place place;

控制器更改:

@PostMapping("/place/add")
public String addPlace(@ModelAttribute Place place, @AuthenticationPrincipal UserDetails currentUser) {
User user = userRepository.findUserByUsername(currentUser.getUsername());
    place.setUserId(user.getId());
    place.getPlaceUrl().setUrl("something_nice");
    placeRepository.save(place);
    return "redirect:/places";
}

现在保存后,我得到:没有可用的消息。lang.NullPointerException

更新2:

我只是混日子才开始工作。我不知道它为什么有效,所以其他人可以解释。

@PostMapping("/place/add")
    public String addPlace(Model model, @ModelAttribute Place place, @AuthenticationPrincipal UserDetails currentUser) {
        PlaceUrl placeUrl = new PlaceUrl();
        User user = userRepository.findUserByUsername(currentUser.getUsername());
        placeUrl.setUrl(place.getName());
        place.setPlaceUrl(placeUrl);
        place.setUserId(user.getId());
        placeUrl.setPlace(place); <-- this line here made it all work
        placeRepository.save(place);
        return "redirect:/places";
    }

我按照别人建议的指南中的说明去做。基本上,我将@OneToOne(mappedBy=“place”)添加到父实体,然后将@OneToOne和@JoinColumn(name=“placeId”)添加到子实体。

共有1个答案

南门承教
2023-03-14

您已在父实体中映射关系,但未在子实体中使用它。相反,通过定义另一个映射,您无法利用级联。解决方案是在PlaceUrl添加mappedBy

@OneToOne(mappedBy = "placeUrl")
private Place place;

或者更好的是,在子级使用mappedBy,这是一种干净的方法。

 类似资料:
  • 我有一个实体: 要创建上述实体并将其保存到JPA存储库中,我将执行以下操作: 由于DB中的表存储了候选对象的FK,我认为设置一个id就足够了。但JPA希望我设置候选对象。这迫使我查询候选存储库。 是否需要从候选库中查询候选人以保存,或者如果我有可用的候选人id,我不能直接设置它?

  • 我在和实体之间有以下一对一的关系: 和 这一切工作得很好,但是如果我添加到类中的字段,并调用,则会失败: 原因:javax。坚持不懈RollbackException:在组织提交事务时出错。冬眠内部的例外情况ConverterImpl。org上的ConvertCommitteException(ExceptionConverterImpl.java:77)。冬眠发动机交易内部的Transactio

  • 问题内容: 我有2个班级:驾驶员和汽车。汽车表在单独的过程中更新。我需要的是在Driver中具有属性,该属性使我可以阅读完整的汽车说明,并仅写入指向现有Car的ID。这是示例: 汽车对象只是典型的JPA对象,没有向后引用驱动程序。 因此,我想通过以下方法实现的目标是:1)我可以使用详细的JSON View阅读完整的汽车描述2)或在简短的JsonView 3中仅阅读汽车的ID 3),最重要的是,在创

  • 问题内容: 也许这是一个愚蠢的问题,但这困扰了我。 我有一个从员工到车辆的双向一对多关系。当我第一次将Employee保留在数据库中时(即它没有分配的ID),我也希望保留其关联的Vehicles。 目前,这对我来说很好,除了我保存的Vehicle实体没有自动映射关联的Employee,并且在数据库中Vehicle表中的employee_id外键列为空。 我的问题是,是否可以在雇员本身被保留的同时保

  • Car对象只是典型的JPA对象,没有对驱动程序的反向引用。 所以我试图通过这个来实现的是: 我可以使用详细的JSON视图阅读完整的汽车说明 或者我可以只读取汽车的Id,简写为jsonview 最重要的是,在创建新的驱动程序时,我只想传入汽车的JSON ID。这样,我就不需要在persist期间对Car进行不确定的读取,而只需要更新ID。 谢谢你。 更新:忘记了,我在创建驱动程序时通过的汽车的ID是

  • 我有两个这样的等级: 和 我想使用hibernate持久化这两个类。字段messagesOfTypeA、messagesOfTypeB和messagesOfTypeC根据消息中的类型字段对消息对象进行分组。 如何使用XML hibernate映射映射MyClass和Message之间的一对多关系?(我正在使用Hibernate 3.6)