简体   繁体   English

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

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

I'v been searching internet for answer, but nothing was working for me.我一直在互联网上寻找答案,但没有什么对我有用。 There is a lot of topics with similar cases but specific details are different in a way that make them unusable for me.有很多类似案例的主题,但具体细节有所不同,这使得它们对我来说无法使用。

So I have two tables: t_item and t_item_info:所以我有两个表:t_item 和 t_item_info:

在此处输入图像描述

item_id field from t_item_info table references id field from t_item table. t_item_info表中的item_id字段引用t_item表中的id字段。 I'm using mysql db and id column form t_item is auto incremented我正在使用 mysql db 和id列形式t_item自动递增

I need to make unidirectional one-to-one mapping in a specific way.我需要以特定方式进行单向一对一映射。 Here are my classes:这是我的课程:

@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;
}

And other one还有一个

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

    private String descr;
}

So the point is that i need Item object to have a reference to ItemInfo object.所以关键是我需要Item object 来引用ItemInfo object。 NOT The other way!不是另一种方式!

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

The other thing is that i need parent ( Item ) id to become id for a child ( ItemInfo )另一件事是我需要父母( Item ) id 成为孩子的 id ( ItemInfo

For example I create Item object with null id and set it's info field with ItemInfo object which also have null id field.例如,我使用 null id 创建Item object 并使用ItemInfo object 设置它的信息字段,其中也有 Z37A6259CC0C1DAE298 FF0BDA 字段。 Like this:像这样:

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

Then when Item object persists hibernate should generate id for parent( Item ) object and set it as itemId field for child( ItemInfo ).然后当项目object 持续存在时 hibernate 应该为父(项目) object 生成 id 并将其设置为子项目( ItemInfo )的 itemId 字段。

I have been trying to achieve this with different hibernate annotations and I noticed that no matter how hard I tried Hibernate always seems to try to persist child object first .我一直在尝试使用不同的 hibernate 注释来实现这一点,我注意到无论我多么努力地尝试 Hibernate 似乎总是首先尝试坚持子 object I noticed it in the logs when I turned sql logging on.当我打开 sql 登录时,我在日志中注意到了这一点。 insert into t_item_info always goes first (and dies because of null id:D)插入 t_item_info 总是先行(并且因为 null id:D 而死)

So the question is: Is it even possible to achieve this and if so what should I change in my code to do so所以问题是:是否有可能实现这一点,如果可以,我应该在我的代码中进行哪些更改才能做到这一点

I hope that what I'm trying to ask makes sens to you given my poor explanations =)鉴于我的解释不佳,我希望我要问的问题对您有意义=)

Why people always insist the child object table in one-to-one associations should be the one with the foreign key is beyond me.为什么人们总是坚持一对一关联中的子表 object 应该是具有外键的表,这超出了我的理解。

Anyway, as a workaround, since both objects share the id and the association is non-optional, you might as well declare the autogenerated key for the child object:无论如何,作为一种解决方法,由于两个对象共享id并且关联是非可选的,您不妨为子 object 声明自动生成的密钥:

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

    private String descr;
}

and then use @MapsId for the parent:然后为父级使用@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;
}

Note that this approach, will, in a sense, fool Hibernate into thinking it is the Item that should be treated as the child object.请注意,这种方法在某种意义上会愚弄 Hibernate 以为它是应该被视为子 object 的Item You have been warned.你被警告了。

While there is an accepted answer here it looks to me like @Secondary table would be a better and more convenient solution: you may have 2 tables at the database level but I do not see any reason that that fact needs be exposed to any client code.虽然这里有一个公认的答案,但在我看来, @Secondary表将是一个更好、更方便的解决方案:您可能在数据库级别有 2 个表,但我认为没有任何理由需要将该事实暴露给任何客户端代码. There does not seem to be a lot of benefit to that?好像没有很多好处? The following gives you a simpler API.下面给大家一个更简单的API。

Entity:实体:

@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: API:

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

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

相关问题 JPA / Hibernate使用共享主键进行单向一对一映射 - JPA / Hibernate unidirectional one-to-one mapping with shared primary key Spring 引导数据 JPA:与共享主键的一对一关系 - Spring Boot Data JPA: One-to-One Relationship with Shared Primary Key JPA 2:通过查找JoinColumn-一对一关系中的共享主键来确定实体ID - JPA 2: Determine an entitys id by looking up JoinColumn - Shared primary key in one-to-one relation 在JPA中共享主键为一对一关系的情况下如何访问对象? - How to access object in case of shared primary key as one-to-one relationship in JPA? 休眠外键一对一单向 - Hibernate One-to-One unidirectional on foreign key 带有反向主外键级联的零到一单向休眠 - Hibernate Zero to One unidirectional with reverse primary foreign key cascade JPA - 无法获得以一对一关系生成的主键 - JPA - Could not get primary key generated in a one-to-one relationship 如何在非主键上使用休眠注释设置单向一对一关系? - how to set unidirectional one-to-one relationship using hibernate annotation on a non-primary key? Sprint Data JPA - 使用共享主键保存父实体的子实体 - Sprint Data JPA - save child entity with parent with shared primary key 如何在不通过休眠中的共享主键以一对一关系插入子对象的情况下保存父实体? - How to save parent entity without inserting child in one to one relationship by shared primary key in hibernate?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM