多个主键表 - Hibernate NonUniqueObjectException

发布于 2024-11-13 11:00:26 字数 2276 浏览 2 评论 0原文

我有一个带有 2 个主键的表(因此它们的组合应该是唯一的)。架构是这样的:

TABLE="INVOICE_LOGS"
INVOICE_NUMBER  PK  non-null
INVOICE_TYPE    PK  non-null
AMOUNT  

当我尝试一次保留多个记录时,我收到此休眠异常:

原因: javax.persistence.PersistenceException: org.hibernate.NonUniqueObjectException: 具有相同对象的不同对象 标识符值已经是 与会话关联: [...InvoiceLog#110105269]

因此,如果我使用下面的代码,我会得到上面的休眠异常。如果我只保留一条记录,它会很好地工作,但如果我尝试像我想做的那样保留一个集合,它就会失败。

    List<InvoiceLog> logs = getLogs();
    for(OvercounterLogDO log: logs) {
        persist(log);
    }

    public void persist(final Object entity) {
        entityManager.persist(entity);
        entityManager.flush();
    }

hibernate映射类如下:

@Component(InvoiceLog.BEAN_NAME)
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
@Entity
@Table(name = "INVOICE_LOGS", uniqueConstraints = {@UniqueConstraint(columnNames = "INVOICE_NUMBER"),@UniqueConstraint(columnNames = "INVOICE_TYPE")} ) 
public class InvoiceLog implements java.io.Serializable {

    private static final long serialVersionUID = -7576525197897271909L;

    protected static final String BEAN_NAME = "invoiceLog";

    private long invoiceNumber;
    private String invoiceType;
    private Double amount;

    public InvoiceLog(){}

    public InvoiceLog(Integer invoiceNumber, String invoiceType,
            Double amount) {
        super();
        this.invoiceNumber = invoiceNumber;
        this.invoiceType = invoiceType;
        this.amount = amount;
    }

    @Id
    @Column(name = "INVOICE_NUMBER", unique = true, nullable = false, precision = 10, scale = 0)
    public long getInvoiceNumber() {
        return invoiceNumber;
    }
    public void setInvoiceNumber(long invoiceNumber) {
        this.invoiceNumber = invoiceNumber;
    }

//  @Id
    @Column(name = "INVOICE_TYPE", nullable = false, length = 4)
    public String getInvoiceType() {
        return invoiceType;
    }
    public void setInvoiceType(String invoiceType) {
        this.invoiceType = invoiceType;
    }

    @Column(name = "AMOUNT", nullable = false, length = 12)
    public Double getAmount() {
        return amount;
    }
    public void setAmount(Double amount) {
        this.amount = amount;
    }

}

I have a table with 2 primary keys (so the combination of both of them should be unique). The schema is like this:

TABLE="INVOICE_LOGS"
INVOICE_NUMBER  PK  non-null
INVOICE_TYPE    PK  non-null
AMOUNT  

When I try to persist multiple records at a time, I get this hibernate exception:

Caused by:
javax.persistence.PersistenceException:
org.hibernate.NonUniqueObjectException:
a different object with the same
identifier value was already
associated with the session:
[...InvoiceLog#110105269]

So if I use the following code below, I get the hibernate exception above. It works fine if I only persist one record but fails if I try to persist a collection like what I'm trying to do.

    List<InvoiceLog> logs = getLogs();
    for(OvercounterLogDO log: logs) {
        persist(log);
    }

    public void persist(final Object entity) {
        entityManager.persist(entity);
        entityManager.flush();
    }

The hibernate mapping class is below:

@Component(InvoiceLog.BEAN_NAME)
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
@Entity
@Table(name = "INVOICE_LOGS", uniqueConstraints = {@UniqueConstraint(columnNames = "INVOICE_NUMBER"),@UniqueConstraint(columnNames = "INVOICE_TYPE")} ) 
public class InvoiceLog implements java.io.Serializable {

    private static final long serialVersionUID = -7576525197897271909L;

    protected static final String BEAN_NAME = "invoiceLog";

    private long invoiceNumber;
    private String invoiceType;
    private Double amount;

    public InvoiceLog(){}

    public InvoiceLog(Integer invoiceNumber, String invoiceType,
            Double amount) {
        super();
        this.invoiceNumber = invoiceNumber;
        this.invoiceType = invoiceType;
        this.amount = amount;
    }

    @Id
    @Column(name = "INVOICE_NUMBER", unique = true, nullable = false, precision = 10, scale = 0)
    public long getInvoiceNumber() {
        return invoiceNumber;
    }
    public void setInvoiceNumber(long invoiceNumber) {
        this.invoiceNumber = invoiceNumber;
    }

//  @Id
    @Column(name = "INVOICE_TYPE", nullable = false, length = 4)
    public String getInvoiceType() {
        return invoiceType;
    }
    public void setInvoiceType(String invoiceType) {
        this.invoiceType = invoiceType;
    }

    @Column(name = "AMOUNT", nullable = false, length = 12)
    public Double getAmount() {
        return amount;
    }
    public void setAmount(Double amount) {
        this.amount = amount;
    }

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

沉溺在你眼里的海 2024-11-20 11:00:26

您当前的映射有一个 Id、invoiceNumber,而不是复合键。因此,它要求发票编号是唯一的,而不是您想要的组合。这就是异常告诉您的内容,它注意到您正在尝试保存具有相同 Id 值的第二条记录。

您需要将两个字段映射为复合键。从您对第二个 @Id 的注释来看,您在某个时刻正朝着这个方向前进。 这里是有关映射组合键的方法的文档

Your current mapping has a single Id, invoiceNumber, not a compound key. As such, it'll demand that the invoiceNumber be unique, not the combination you want. That's what the exception is telling you, it's noticing you're trying to save a second record with the same Id value.

You need to map the two fields as a composite key. It looks from your commenting out the second @Id that you were going in that direction at some point. Here's the documentation on methods for mapping the composite key.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文