2011-06-01 117 views
1

我有一個表有2個主鍵(所以他們兩個的組合應該是唯一的)。該模式是這樣的:多主鍵表 - 休眠NonUniqueObjectException

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

} 

回答

3

您當前的映射具有一個單一的標識,invoiceNumber,而不是化合物鍵。因此,它會要求invoiceNumber是唯一的,而不是你想要的組合。這是例外情況告訴你的,它注意到你正試圖用相同的Id值保存第二條記錄。

您需要將兩個字段映射爲組合鍵。它看起來從你的第二個@Id註釋出你在某個時間點朝着那個方向。 Here's the documentation關於映射組合鍵的方法。