繁体   English   中英

JPA Hibertane 单向一对一与共享主键先保存父级 NO REVERSE

[英]JPA Hibertane unidirectional one-to-one with shared primary key save parent first NO REVERSE

我一直在互联网上寻找答案,但没有什么对我有用。 有很多类似案例的主题,但具体细节有所不同,这使得它们对我来说无法使用。

所以我有两个表:t_item 和 t_item_info:

在此处输入图像描述

t_item_info表中的item_id字段引用t_item表中的id字段。 我正在使用 mysql db 和id列形式t_item自动递增

我需要以特定方式进行单向一对一映射。 这是我的课程:

@Entity
@Table(name = "t_item")
public class Item {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, optional = false)
    @PrimaryKeyJoinColumn(name = "id", referencedColumnName = "item_id")
    private ItemInfo info;
}

还有一个

@Entity
@Table(name = "t_item_info")
public class ItemInfo {
    @Id
    private Long itemId;

    private String descr;
}

所以关键是我需要Item object 来引用ItemInfo object。 不是另一种方式!

Item -> ItemInfo   --YES
Item <- ItemInfo   --NO

另一件事是我需要父母( Item ) id 成为孩子的 id ( ItemInfo

例如,我使用 null id 创建Item object 并使用ItemInfo object 设置它的信息字段,其中也有 Z37A6259CC0C1DAE298 FF0BDA 字段。 像这样:

{
  "id": null,
  "name": "Some name",
  "info": {
    "itemId": null,
    "descr": "some descr"
  }
}

然后当项目object 持续存在时 hibernate 应该为父(项目) object 生成 id 并将其设置为子项目( ItemInfo )的 itemId 字段。

我一直在尝试使用不同的 hibernate 注释来实现这一点,我注意到无论我多么努力地尝试 Hibernate 似乎总是首先尝试坚持子 object 当我打开 sql 登录时,我在日志中注意到了这一点。 插入 t_item_info 总是先行(并且因为 null id:D 而死)

所以问题是:是否有可能实现这一点,如果可以,我应该在我的代码中进行哪些更改才能做到这一点

鉴于我的解释不佳,我希望我要问的问题对您有意义=)

为什么人们总是坚持一对一关联中的子表 object 应该是具有外键的表,这超出了我的理解。

无论如何,作为一种解决方法,由于两个对象共享id并且关联是非可选的,您不妨为子 object 声明自动生成的密钥:

@Entity
@Table(name = "t_item_info")
public class ItemInfo {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long itemId;

    private String descr;
}

然后为父级使用@MapsId

@Entity
@Table(name = "t_item")
public class Item {
    @Id
    private Long id;

    private String name;

    @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, optional = false)
    @JoinColumn(name = "id")
    @MapsId
    private ItemInfo info;
}

请注意,这种方法在某种意义上会愚弄 Hibernate 以为它是应该被视为子 object 的Item 你被警告了。

虽然这里有一个公认的答案,但在我看来, @Secondary表将是一个更好、更方便的解决方案:您可能在数据库级别有 2 个表,但我认为没有任何理由需要将该事实暴露给任何客户端代码. 好像没有很多好处? 下面给大家一个更简单的API。

实体:

@Entity
@Table(name = "t_item")
@SecondaryTable("t_item_info",  pkJoinColumns={
        @PrimaryKeyJoinColumn(name="id", referencedColumnName="item_id")})
public class Item {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    @Colulumn(name = "description", table= "t_item_info"")
    private String description;
}

API:

{
  "id": null,
  "name": "Some name",
  "descr": "some descr"
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM