多个主键表 - Hibernate NonUniqueObjectException

时间:2011-06-01 16:38:43

标签: java oracle hibernate primary-key

我有一个包含2个主键的表(因此两者的组合应该是唯一的)。架构是这样的:

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

当我尝试一次持有多个记录时,我得到了这个hibernate异常:

  

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

因此,如果我使用下面的代码,我会得到上面的hibernate异常。如果我只保留一条记录但是如果我试图坚持像我正在尝试做的那样的集合则会失败。

    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;
    }

}

1 个答案:

答案 0 :(得分:3)

您当前的映射具有单个Id,invoiceNumber,而不是复合键。因此,它要求invoiceNumber是唯一的,而不是您想要的组合。这就是异常告诉你的,它注意到你试图用相同的Id值保存第二条记录。

您需要将这两个字段映射为复合键。从你评论出来的第二个@Id来看,你在某个方面正朝着那个方向前进。 Here's the documentation关于映射组合键的方法。