【问题标题】:Save Parent Object and list of child object Same Time in hibernate在休眠中同时保存父对象和子对象列表
【发布时间】:2014-05-29 07:53:36
【问题描述】:

这是我的实体类

    @Entity
        @Table(name="hdr_info")
        public class HdrInfo implements Serializable {
            private static final long serialVersionUID = 1L;

            @Id
            @Column(name="hdr_sr_no")
            @GeneratedValue(strategy=GenerationType.IDENTITY)
            private Integer HdrSrNo;

            @Column(name="comp_cd")
            private Integer compCd;

            //bi-directional many-to-one association to EppsMmMtrlReqDtl
            @OneToMany(mappedBy="hdrInfo")
            @Cascade(CascadeType.SAVE_UPDATE)
            private List<DetailInfo> detailInfo;
            //getters and setters
        }

详细信息实体类

        @Entity
        @Table(name="detail_info")
        public class DetailInfo implements Serializable {
            private static final long serialVersionUID = 1L;

            @Id
            @GeneratedValue(strategy=GenerationType.IDENTITY)
            @Column(name="dtl_sr_no")
            private Integer dtlSrNo;

            @Column(name="active_yn")
            private String activeYn;

            @Column(name="short_close_qty")
            private BigDecimal shortCloseQty;

            @Column(name="short_close_rsn")
            private String shortCloseRsn;

            @Column(name="short_close_yn")
            private String shortCloseYn;

            @Column(name="sugg_brand")
            private String suggBrand;

            @Column(name="terminal_id")
            private String terminalId;

            @Column(name="transaction_stage")
            private Integer transactionStage;

            //bi-directional many-to-one association to EppsMmMtrlReqHdr
            @ManyToOne
            @JoinColumn(name="hdr_sr_no", nullable = false)
            private HdrInfo hdrInfo;

               //getters and setters
        }

主要

public static void main(String[] args) {
    Session session = HibernateUtil.getSessionFactory().openSession();

    HdrInfo hdr =new HdrInfo();
    hdr.setCompCd(1);
    List<DetailInfo> lst=new ArrayList<DetailInfo>();
    for (int j = 0; j < 3; j++) {                       
        DetailInfo dtl=new DetailInfo();

        dtl.setTransactionStage(Integer.parseInt("1"));
        dtl.setTerminalId("linuxPc01");
        dtl.setActiveYn("Y");

        dtl.setShortCloseYn("Y");

        dtl.setHdrInfo(hdr);
        lst.add(dtl);
    }
    hdr.setEppsMmMtrlReqDtls(lst);
    session.saveOrUpdate(hdr);
    session.getTransaction().commit();
}

现在,如果我运行主类来保存带有 DtlInfoClass 列表的 HderInfo 类,则在保存 DtlInfo 列表时发现相同对象标识符的错误,现在 DtlInfo 的主键也自动递增,那么什么是正确的解决方案?帮帮我!!!

【问题讨论】:

  • 您的主要方法中有错误。您创建了 3 个 DetailInfo 对象并将其丢弃。您应该将其添加到 HdrInfo.detailInfo 列表中
  • sry 忘了添加,会更正它,但它也会给我同样的错误
  • 还有更多错误... mappedBy="HdrInfo" 应该是 mappedBy="hdrInfo" 并且您没有开始交易。并且您必须初始化 arraylist 详细信息。比主要添加它,这对我来说没有问题。
  • 并且错误是 org.hibernate.NonUniqueObjectException:具有相同标识符值的不同对象已与会话关联:

标签: java hibernate hibernate-mapping


【解决方案1】:

试试这样:

HdrInfo

private List<DetailInfo> detailInfos = new ArrayList<DetailInfo>();

public void addDetailInfo(DetailInfo detailInfo) {
    detailInfo.setParent(this);
    detailInfos.add(detailInfo);
}

public void removeDetailInfo(DetailInfo detailInfo) {
    detailInfos.remove(detailInfo);
    if (detailInfo != null) {
        detailInfo.setParent(null);
    }
}

主要

Session session = HibernateUtil.getSessionFactory().openSession();
Transaction tx = null;
try {
    tx = session.beginTransaction();

    HdrInfo hdr = new HdrInfo();
    hdr.setCompCd(1);
    for (int j = 0; j < 3; j++) {                       
        DetailInfo dtl=new DetailInfo();

        dtl.setTransactionStage(Integer.parseInt("1"));
        dtl.setTerminalId("linuxPc01");
        dtl.setActiveYn("Y");

        dtl.setShortCloseYn("Y");

        hdr.addDetailInfo(dtl);
    }
    session.saveOrUpdate(hdr);

    tx.commit();
}
catch (RuntimeException e) {
    if (tx != null) tx.rollback();
    throw e;
}
finally {
    sess.close();
}
  1. 您需要显式启动/提交/回滚事务。
  2. 始终close the session 释放分配的资源(数据库连接)
  3. 最好从头初始化所有子集合
  4. 在具有双向关联时,最好添加添加/删除实用程序

【讨论】:

    【解决方案2】:

    这里有一些建议,然后尝试一下;

    1. 我确信您正在尝试将新对象实例作为新对象实例持久化到 DB

      //session.saveOrUpdate(hdr);
      session.save(hdr);
      
    2. 在实体类中覆盖 equals() 和 hashCode()

    3. 正如@pL4Gu33所说,注意mappedBy的拼写

    4. 在没有数据库更新操作之前打开事务

      session.getTransaction().begin();
      

    【讨论】:

    • 您确实意识到 session.save() 的作用与 session.saveOrUpdate() 完全相同。唯一的区别是使用 session.saveOrUpdate() 如果您的对象已经存在于数据库中,则不会引发异常。如果这确实解决了问题,那么系统存在比通过级联获取要保存的集合对象远更深的问题。 -1
    • 是的,我知道 save() 和 saveOrUpdate() 之间的区别。那么你对这个问题有什么建议呢?
    • 删除关于 session.save() 的建议,我完全同意覆盖 equals 和 hashcode,但不更改为 session.save(),这对实际解决方案具有误导性。如果您对此感到困扰,那么 OP 的问题在于他的级联类型和关系映射。我会解决的,但我必须回家:P
    • 抱歉,我确定问题在于测试是否作为新对象持久存在,并且与合并到持久上下文(缓存内存)中的任何状态无关。 :D
    • 我刚刚这样做了,但是得到了错误---org.hibernate.NonUniqueObjectException:具有相同标识符值的不同对象已经与会话相关联:
    猜你喜欢
    • 2015-04-27
    • 1970-01-01
    • 2014-12-11
    • 2021-05-22
    • 1970-01-01
    • 2013-02-22
    • 1970-01-01
    • 2018-01-11
    • 2021-07-23
    相关资源
    最近更新 更多