oracle 多主键表 - Hibernate NonUniqueObjectException
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6204673/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Multiple Primary Keys Table - Hibernate NonUniqueObjectException
提问by Steve
I have a table with 2 primary keys (so the combination of both of them should be unique). The schema is like this:
我有一个带有 2 个主键的表(因此它们的组合应该是唯一的)。架构是这样的:
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]
引起:javax.persistence.PersistenceException:org.hibernate.NonUniqueObjectException:具有相同标识符值的不同对象已经与会话关联:[...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;
}
}
回答by Stevi Deter
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.
您当前的映射具有单个 Id、invoiceNumber,而不是复合键。因此,它会要求 invoiceNumber 是唯一的,而不是您想要的组合。这就是异常告诉你的,它注意到你正试图用相同的 Id 值保存第二条记录。
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 documentationon methods for mapping the composite key.
您需要将这两个字段映射为复合键。从你的第二个评论中可以@Id
看出你在某个时候正朝着那个方向前进。这是有关映射复合键的方法的文档。