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)

我尝试了很多东西。切换我声明 ma​​ppedByItemItemInfo 在这种情况下,一切都停止工作,因为 ItemInfo 试图首先得到持久化。我尝试了optional = false\truenullable = 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无法自动设置)的主要内容,如果未能解决你的问题,请参考以下文章

hibernate系列之四

数据库中的关键字——字段(列)记录(元组)表主键外键

hibernate学习---关联关系映射

mysql 语句 字段 和结构主键外键的增删改

Hibernate使用注意事项

hibernate 联合主键一对多用注解怎么设置?