Hibernate JPA与共享主键外键字段的一对一双向映射为空(hb无法自动设置)
Posted
技术标签:
【中文标题】Hibernate JPA与共享主键外键字段的一对一双向映射为空(hb无法自动设置)【英文标题】:Hibernate JPA one to one bidirectional mapping with shared primary key foreign key field is null (hb can't set it automatically) 【发布时间】:2020-07-27 17:50:04 【问题描述】:所以我在最后一天尝试获得一些单向的一对一映射,经过一些测试后,我决定尝试另一种方法。当我试图坚持我的实体时偶然发现了一个问题。我找不到一种方法来强制休眠同时来回填充我的外键字段和引用。它只将它们设置为一种方式,而不是另一种方式:
Item ---> ItemInfo (I populate info field manually in constructor)
Item <-x- ItemInfo (hibernate doesn't set item field on persist)
所以当我尝试坚持 Item
实体时,我从 @MapsId
得到异常:attempted to assign id from null one-to-one property [by.test.hm.ItemInfo.item]
我的桌子:
t_item_info(item_id)
引用 t_item(id)
字段。只有t_item(id)
列是自动递增的
我的课程:
@Entity
@Table(name = "t_item")
class Item
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToOne(mappedBy = "item", cascade = CascadeType.ALL,
fetch = FetchType.LAZY, orphanRemoval = true, optional = false)
private ItemInfo info;
private String name;
还有一个:
@Entity
@Table(name = "t_item_info")
class ItemInfo
@Id
private Long itemId;
@MapsId
@OneToOne
@JoinColumn(name = "item_id", referencedColumnName = "id")
private Item item;
private String descr;
我如何创建和持久化对象:
Item item = new Item(
null,
new ItemInfo(null, "Somde description"),
"Some name"
);
itemRepo.save(item);
例外:
org.hibernate.id.IdentifierGenerationException: 试图分配 id 从 null 一对一属性 [by.test.hm.ItemInfo.item] 在 org.hibernate.id.ForeignGenerator.generate(ForeignGenerator.java:87) 在 org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:115) 在 org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:185) 在 org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:128) 在 org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:113)
我尝试了很多东西。切换我声明 mappedBy 从 Item
到 ItemInfo
在这种情况下,一切都停止工作,因为 ItemInfo
试图首先得到持久化。我尝试了optional = false\true
和nullable = false\true
的所有可能组合,但似乎没有任何效果=(
我知道我可以手动设置引用,但异常会消失,我知道我可以使用 @PostPersist
来设置它,但是当休眠自动为我执行此操作时,我正在寻找答案
PS:我发布了关于单向映射的类似问题,我是新来的,所以我希望在为类似问题创建新问题时我没有做错
【问题讨论】:
您好,您尝试在 oneToOne 注释中使用 cascade.persist 吗? @Ruokki 我正在使用CascadeType.ALL
,据我所知,它都包含 PERSIST。我试过以防万一 - 没有运气=(
尝试在您的 ItemInfo 中使用 à @Generated info
【参考方案1】:
@Entity
@Table(name = "t_item")
class Item
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToOne(mappedBy = "item", cascade = CascadeType.ALL,
fetch = FetchType.LAZY, orphanRemoval = true, optional=false)
private ItemInfo info;
@Column(name="name)
private String name;
// Getters and setters omitted for brevity
private void setItemInfo(ItemInfo info)
if (info == null)
if (this.info != null)
this.info.setInfo(null);
else
info.setInfo(this);
this.info = info;
@Entity
@Table(name = "t_item_info")
class ItemInfo
@Id
private Long itemId;
@OneToOne
@MapsId
@JoinColumn(name="item_id)
private Item item;
@Column(name="description")
private String description;
// Getters and setters omitted for brevity
超出主题,但您的课程名称相同。
试试上面的代码........
【讨论】:
嗯,它可以工作,但我正在尝试让休眠自动为我分配字段(如在你的 setter 变体中)以上是关于Hibernate JPA与共享主键外键字段的一对一双向映射为空(hb无法自动设置)的主要内容,如果未能解决你的问题,请参考以下文章