@OneToMany与复合键的关系 [英] @OneToMany relationship with Composite key

查看:187
本文介绍了@OneToMany与复合键的关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下模型(忽略不相关/明显的代码,例如setter和getters):

  @Entity 
公共类发票{
@Id //序列生成
私有长期invoiceId;
$ b $ @ @ToToMany(fetch = FetchType.EAGER)
@JoinColumn(name =invoiceId,referencedColumnName =invoiceId)
@OrderBy(id.itemNumber)
列表<项目> items = new ArrayList< Item>();
}


@Entity
public class Item {
@EmbeddedId
private ItemPK id;
}


@Embeddable
public class ItemPK {
private long invoiceId;
私人长itemNumber;



$ b

不能更改数据库结构,因为它是传统数据库:(



itemNumber基本上是一个从零开始的索引。



如果我使用现有的发票,现有的项目,并在列表中添加2个新项目,当试图更新发票对象时遇到各种问题:

如果我留下ItemPK null, :
org.hibernate.TransientObjectException:object是一个未保存的瞬态实例 - 在合并之前保存瞬态实例


如果我尝试自己填充ItemPK的值(发票和索引的ID),则会得到: org.hibernate.NonUniqueObjectException:具有相同标识符值的不同对象已关联会话 (在数据库中已经有一个发票项目,它具有发票ID和索引= 0,就像我的新项目列表中的第一个对象)。



I f我试着离开invoiceId null(在ItemPK对象中),我得到: java.sql.BatchUpdateException:ORA-01400:无法将NULL插入(Item。invoiceId)

有没有办法让Hibernate / JPA处理这个问题?
或者我需要完全删除关联,将列表定义为@Transient并填写并保存到我的服务类中?



谢谢。 / p>

解决方案

在这里您实际上具有双向关联,因为Item实体中的invoiceId实际上是发票的外键。因此,您应该将该关联映射为双向关联,并使用 @MapsId 注释。它的javadoc有一个例子。


I have the following model (ignoring irrelevant/obvious code, like setters and getters):

@Entity
public class Invoice {
    @Id // sequence generated
    private Long invoiceId;

    @OneToMany(fetch = FetchType.EAGER)
    @JoinColumn(name = "invoiceId", referencedColumnName = "invoiceId")
    @OrderBy("id.itemNumber")
    List<Item> items = new ArrayList<Item>();
}


@Entity
public class Item {
    @EmbeddedId
    private ItemPK id;
}


@Embeddable
public class ItemPK {
    private Long invoiceId;
    private Long itemNumber;
}

Can't change the DB structure, as it's a legacy DB :(

The itemNumber is basically an index that starts at zero.

If I take an existing Invoice and just remove the existing item and add 2 new items in the list, when trying to update the Invoice object I run into all sorts of problems:

If I leave the ItemPK null, I get: org.hibernate.TransientObjectException: object is an unsaved transient instance - save the transient instance before merging

If I try to fill the values of ItemPK myself (the id of the invoice and the index), I get: org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session (there already is an invoice item in the DB and it has the invoice id and the index = 0, just like the first object in my new list of items).

If I try to leave the invoiceId null (in the ItemPK object), I get: java.sql.BatchUpdateException: ORA-01400: cannot insert NULL into ("Item"."invoiceId")

Is there anyway to let Hibernate/JPA handle this ? Or do I need to completely remove the association, defined the list as @Transient and just fill it and save it in my service classes ?

Thanks.

解决方案

You effectively have a bidirectional association here, since the invoiceId in the Item entity is in fact a foreign key to the Invoice. You should thus map the association as a bidirectional one, and use the @MapsId annotation. Its javadoc has an example.

这篇关于@OneToMany与复合键的关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆