多主键表 - 休眠NonUniqueObjectException
问题描述:
我有一个表有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;
}
}
答
您当前的映射具有一个单一的标识,invoiceNumber,而不是化合物键。因此,它会要求invoiceNumber是唯一的,而不是你想要的组合。这是例外情况告诉你的,它注意到你正试图用相同的Id值保存第二条记录。
您需要将两个字段映射为组合键。它看起来从你的第二个@Id
注释出你在某个时间点朝着那个方向。 Here's the documentation关于映射组合键的方法。