JPA Hibertane 单向 one-to-one 共享主键保存 parent 首先 NO REVERSE
JPA Hibertane unidirectional one-to-one with shared primary key save parent first NO REVERSE
我一直在互联网上寻找答案,但没有任何效果。有很多主题具有相似的案例,但具体细节不同,使它们对我来说无法使用。
所以我有两个 table:t_item 和 t_item_info:
item_id 字段来自 t_item_info table 引用 id 来自 t_item table 的字段。我正在使用 mysql 数据库和 id 列形式 t_item 是自动递增的
我需要以特定方式制作单向 one-to-one映射。这是我的 类:
@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
另一件事是我需要 parent (Item) id 才能成为 child (ItemInfo)
例如,我使用空 ID 创建 Item object 并将它的 info 字段设置为 ItemInfo object 也有 null id 字段。像这样:
{
"id": null,
"name": "Some name",
"info": {
"itemId": null,
"descr": "some descr"
}
}
然后当 Item object 持续存在时,hibernate 应该为 parent(Item) object 并将其设置为 child(ItemInfo).
的 itemId 字段
我一直在尝试使用不同的休眠注释来实现这一点,我注意到无论我多么努力地尝试休眠,似乎总是首先尝试坚持 child object。当我打开 sql 登录时,我在日志中注意到了它。 insert into t_item_info 总是先行(并且因为 null id 而死 :D)
所以问题是:是否有可能实现这一点,如果可以,我应该在我的代码中更改什么才能做到这一点
鉴于我糟糕的解释,我希望我想问的问题对你有意义 =)
为什么人们总是坚持一对一关联中的子对象 table 应该是带有外键的对象,我无法理解。
无论如何,作为一种解决方法,由于两个对象共享 id
并且关联是非可选的,您不妨为子对象声明自动生成的密钥:
@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,使其认为应该将 Item
视为子对象。您已收到警告。
虽然这里有一个可接受的答案,但在我看来 @Secondary
table 会是一个更好更方便的解决方案:您可能在数据库级别有 2 个 table但我看不出有任何理由需要将该事实暴露给任何客户端代码。好像没有什么好处吧?下面给大家一个更简单的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"
}
我一直在互联网上寻找答案,但没有任何效果。有很多主题具有相似的案例,但具体细节不同,使它们对我来说无法使用。
所以我有两个 table:t_item 和 t_item_info:
item_id 字段来自 t_item_info table 引用 id 来自 t_item table 的字段。我正在使用 mysql 数据库和 id 列形式 t_item 是自动递增的
我需要以特定方式制作单向 one-to-one映射。这是我的 类:
@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
另一件事是我需要 parent (Item) id 才能成为 child (ItemInfo)
例如,我使用空 ID 创建 Item object 并将它的 info 字段设置为 ItemInfo object 也有 null id 字段。像这样:
{
"id": null,
"name": "Some name",
"info": {
"itemId": null,
"descr": "some descr"
}
}
然后当 Item object 持续存在时,hibernate 应该为 parent(Item) object 并将其设置为 child(ItemInfo).
的 itemId 字段我一直在尝试使用不同的休眠注释来实现这一点,我注意到无论我多么努力地尝试休眠,似乎总是首先尝试坚持 child object。当我打开 sql 登录时,我在日志中注意到了它。 insert into t_item_info 总是先行(并且因为 null id 而死 :D)
所以问题是:是否有可能实现这一点,如果可以,我应该在我的代码中更改什么才能做到这一点
鉴于我糟糕的解释,我希望我想问的问题对你有意义 =)
为什么人们总是坚持一对一关联中的子对象 table 应该是带有外键的对象,我无法理解。
无论如何,作为一种解决方法,由于两个对象共享 id
并且关联是非可选的,您不妨为子对象声明自动生成的密钥:
@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,使其认为应该将 Item
视为子对象。您已收到警告。
虽然这里有一个可接受的答案,但在我看来 @Secondary
table 会是一个更好更方便的解决方案:您可能在数据库级别有 2 个 table但我看不出有任何理由需要将该事实暴露给任何客户端代码。好像没有什么好处吧?下面给大家一个更简单的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"
}