当前位置: 首页 > 知识库问答 >
问题:

Hibernate -包含父实体的持久化子实体

衡玄裳
2023-03-14

尝试获取父实体(Msg)的实体,其中父PK (msg_id)是子实体中的FK时,尝试保持子实体(MsgRetry)时出错。

错误,如:org.hibernate.id.IdentifierGenerationException:试图从null一对一属性分配id

父实体,不需要知道子实体(至少我认为它不需要知道)。一旦子实体被持久化,我就会尝试也持久化父实体。我可以通过在子实体中没有父实体并调用关联的存储库来解决这个问题。但是,我不认为它像我尝试的那样干净,但显然更困难/复杂。

如果这是一个好的解决方案,感谢任何关于最佳实践或如何实现这一点的建议。

表:

型号:

@Entity
@Table(name="msg")
public class Msg {
    
    @Id
    @Column(name = "msg_id")
    @GeneratedValue(strategy = generationtype.sequence, generator = "msg_id_seq_gen")
    @SequenceGenerator(name = "msg_id_seq_gen", sequencename = "msg_id_seq", allocationsize = 1)
    private Long msgId;
    
    @Column(name = "msg_status", nullable = false)
    private String msgStatus;
    
    ...
    
    //getters setters
}
@Entity
@Table(name = "msg_retry")
public class MsgRetry implements Serializable{

    private static final long serialVersionUID = -7637385223556379976L;

    @Id
    @Column(name = "msg_id")
    private Long msgId;
    
    @OneToOne
    @JoinColumn(name="msg_id", referencedColumnName = "msg_id")
    private Msg msg;
    
    @Column(name = "count")
    private Long count;
    
    @Generated(value = GenerationTime.ALWAYS)
    @Column(name = "timestamp")
    private Date timestamp;
    
    
    
    public MsgRetry() {
    }

    public MsgRetry(Msg msg, Long count) {
        this.msg = msg;
        this.count = count;
    }
    
    public MsgRetry(Long msgId, Long count) {
        this.msgId = msgId;
        this.count = count;
    }
    
    public Msg getMsg() {
        return msg;
    }

    public void setMsg(Msg msg) {
        this.msg = msg;
    }
@Repository
public interface MsgRetryRepository extends JpaRepository<MsgRetry, Long>{

}
@Test
    public void testSaveMsgByMsgIdRetry() {
        
        msgRetryRepository.deleteAll();
        List<Msg> msgs = msgRepository.findAll();
        
        MsgRetry msgRetry = new MsgRetry(msgs.get(0).getMsgId(), 1L);
        
        msgRetry = msgRetryRepository.save(msgRetry);
        assertNotNull(msgRetry.getMsg());  // fails to load Msg entity
        LOG.info("msgRetry: {}", msgRetry);
    }
@Test
    public void testSaveMsgRetryByMsg() {
        
        msgRetryRepository.deleteAll();
        List<Msg> msgs = msgRepository.findAll();
        
        MsgRetry msgRetry = new MsgRetry(msgs.get(0), 1L);
        
        msgRetry = msgRetryRepository.save(msgRetry);
        assertNotNull(msgRetry.getMsg());
        LOG.info("msgRetry: {}", msgRetry);
    }

错误:org.springframework.orm.jpa.JpaSystemException:必须在调用保存():msgtest.MsgRetry之前手动分配此类的id;

共有1个答案

邓鸿雪
2023-03-14

首先,整理您的< code > MsgRetry id。FK应该够好了。

@Entity
@Table(name = "msg_retry")
public class MsgRetry {
    @Id
    @ManyToOne(optional = false)
    @JoinColumn(name = "msg_id")
    private Msg msg;
    
    @Column(name = "count")
    private Long count;
    
    @Generated(value = GenerationTime.ALWAYS)
    @Column(name = "timestamp")
    private Date timestamp;
    
    public Msg getMsg() { return msg; }
         
    public void setMsg(Msg msg) { this.msg = msg; }
}

接下来,确保 MsgRetryRepository 已正确子分类:

public interface MsgRetryRepository extends CrudRepository<MsgRetry, Msg>
{
  // Empty for now
}

最后,以正确的方式查询MsgRetry

public class BizLogic {

    MsgRetryRepository retryRepo
    
    public MsgRetry retry(Msg msg, String msgStatus) {
    
        MsgRetry mr = retryRepo.findById(msg);        
        if (mr !=null) {
            // XXX I cannot tell from your logic what you are doing here.
            retryRepo.save(mr);
        }   
    }
}

您的持久性层是什么?也许您可以打开调试并访问日志以查看引擎盖下发生的情况。

 类似资料:
  • 问题内容: 我正在尝试将实体扩展为用于填充超类字段的非实体。问题是,当我尝试保存它时,Hibernate会抛出MappingException。这是因为即使我将ReportParser强制转换为Report,但运行时实例仍然是ReportParser,因此Hibernate抱怨它是一个未知的实体。 ReportParser仅用于填写字段。 尝试将其投射到报告中并保存 在转移到ORM之前,我已经使用

  • 我有一个实体,它已经持久化,并希望将其添加到新生成的父实体(尚未持久化)。如果我尝试持久化父级,我会得到错误“分离的实体传递到持久化:model.child”。我想我必须以某种方式为孩子调用“EntityManager.merge()”,而不是“EntityManager.persisted()”。但是我没有显式调用persisted。这由“cascade=cascadetype.all”注释处理

  • 这个网站上没有一个类似的问题能够解决我的问题。 错误:org.hibernate.persistentobjectexception:传递给persist:healthcheckapi.model.checks的分离实体 示例JSON健康对象: 请注意,这两个对象的ID都是自动生成的,我认为这是问题的一部分。

  • 我正试图实现与hibernate的许多单向关系。问题是,当我试图向数据库中添加一些值时,我遇到了以下错误: 运行时发生异常。null:InvocationTargetException:未能执行ApplicationRunner:传递给persist:dnd35cg的分离实体。模型DND类;嵌套的异常是org。冬眠PersistentObjectException:传递给persist:dnd35

  • 我有一个实体,它已经被持久化了,想把它添加到一个新生成的父实体(还没有持久化)。如果我尝试持久化父级,那么我会得到错误“Detached entity pass to persist:model.child”。我认为我必须以某种方式为孩子调用“EntityManager.merge()”,而不是“EntityManager.Persist()”。但我没有显式调用persist。这是由“Cascad

  • 问题内容: 我们使用的是带有Hazelcast 3.6.1 2级缓存的Hibernate 3.5.6-Final。 情况 我和具有Hibernate设置的实体之间存在双向,一对多关系。实体类定义如下: 父级的Hibernate映射定义如下: 子项的hibernate映射定义如下: 现在,当前代码向中添加了,如下所示: 问题是第二行代码导致Hibernate加载 所有 子代。在我们的设置中,这是一个