CREATE TABLE GUSERPRO
(
USER_NAME VARCHAR2(20 BYTE),
SYSTEM VARCHAR2(8 BYTE),
PROCESS VARCHAR2(8 BYTE),
LOGIN_TIME NUMBER,
LOGIN_DATE DATE,
LOGOUT_TIME NUMBER,
LOGOUT_DATE DATE,
TOTAL_ELAPSED NUMBER,
TOTAL_LOGINS NUMBER
)
TABLESPACE ERIP_D
PCTUSED 0
PCTFREE 10
INITRANS 1
MAXTRANS 255
STORAGE (
INITIAL 64K
NEXT 1M
MINEXTENTS 1
MAXEXTENTS 2147483645
PCTINCREASE 0
BUFFER_POOL DEFAULT
)
LOGGING
NOCOMPRESS
NOCACHE
NOPARALLEL
MONITORING
ENABLE ROW MOVEMENT;
异常堆栈引用此约束:
CREATE UNIQUE INDEX GUSERPRO_N1 ON GUSERPRO
(USER_NAME, SYSTEM, PROCESS)
LOGGING
TABLESPACE ERIP_D
PCTFREE 10
INITRANS 2
MAXTRANS 255
STORAGE (
INITIAL 64K
NEXT 1M
MINEXTENTS 1
MAXEXTENTS 2147483645
PCTINCREASE 0
BUFFER_POOL DEFAULT
)
NOPARALLEL;
尝试将记录更新到Oracle数据库时,我收到此错误,但并非总是如此,有些情况我得到此错误。如果我创建一个新记录然后更新它工作正常。如果我尝试更新现有记录,则会抛出此错误。 请帮我摆脱这个。
org.springframework.dao.DataIntegrityViolationException:
Could not execute JDBC batch update;
SQL [update PDOXDATA_GUSERPRO set PROCESS=?, SYSTEM=? where USER_NAME=?];
constraint [PDOXDATA_GUSERPRO_N1];
nested exception is org.hibernate.exception.ConstraintViolationException:
Could not execute JDBC batch update
<< rest of error stack >>
以下是相关课程:
/**
*
*/
package com.lv.rs.accessautomation.common.vo;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
/**
* @author tp50148
*
*/
@Entity
@Table(name="PDOXDATA_GUSERPRO"/*,uniqueConstraints = {@UniqueConstraint(columnNames = "userName")}*/)
public class EripUserProVO implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
@Id
@Column(name = "USER_NAME")
private String userName;
@Column(name = "SYSTEM")
private String system;
@Column(name = "PROCESS")
private String process;
@OneToMany(cascade = CascadeType.ALL,fetch = FetchType.LAZY,orphanRemoval = true)
@JoinColumn(name="USER_NAME")
private List<EripGtSignatVO> eripGtSignatVO = new ArrayList<EripGtSignatVO>();
@OneToMany(cascade = CascadeType.ALL,fetch = FetchType.LAZY,orphanRemoval = true)
@JoinColumn(name="USER_NAME")
private List<EripGUsersVO> eripGUsersVO = new ArrayList<EripGUsersVO>();
@OneToMany(cascade = CascadeType.ALL,fetch = FetchType.LAZY,orphanRemoval = true)
@JoinColumn(name="USERNAME")
private List<EripUserLocationVO> eripUserLocationVO = new ArrayList<EripUserLocationVO>();
@OneToMany(cascade = CascadeType.ALL,fetch = FetchType.LAZY,orphanRemoval = true)
@JoinColumn(name="USER_USER")
private List<Eripcpa95VO> eripcpa95VO = new ArrayList<Eripcpa95VO>();
@OneToMany(cascade = CascadeType.ALL,fetch = FetchType.LAZY,orphanRemoval = true)
@JoinColumn(name="USERNAME")
private List<EriporaSacUserVO> eriporaSacUserVO = new ArrayList<EriporaSacUserVO>();
@OneToMany(cascade = CascadeType.ALL,fetch = FetchType.LAZY,orphanRemoval = true)
@JoinColumn(name="SACUSER_USERNAME")
private List<EriporaSacAccessVO> eriporaSacAccessVO = new ArrayList<EriporaSacAccessVO>();
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getSystem() {
return system;
}
public void setSystem(String system) {
this.system = system;
}
public String getProcess() {
return process;
}
public void setProcess(String process) {
this.process = process;
}
public List<EripGtSignatVO> getEripGtSignatVO() {
return eripGtSignatVO;
}
public void setEripGtSignatVO(List<EripGtSignatVO> eripGtSignatVO) {
this.eripGtSignatVO = eripGtSignatVO;
}
public List<EripGUsersVO> getEripGUsersVO() {
return eripGUsersVO;
}
public void setEripGUsersVO(List<EripGUsersVO> eripGUsersVO) {
this.eripGUsersVO = eripGUsersVO;
}
public List<EripUserLocationVO> getEripUserLocationVO() {
return eripUserLocationVO;
}
public void setEripUserLocationVO(List<EripUserLocationVO> eripUserLocationVO) {
this.eripUserLocationVO = eripUserLocationVO;
}
public List<Eripcpa95VO> getEripcpa95VO() {
return eripcpa95VO;
}
public void setEripcpa95VO(List<Eripcpa95VO> eripcpa95vo) {
eripcpa95VO = eripcpa95vo;
}
public List<EriporaSacUserVO> getEriporaSacUserVO() {
return eriporaSacUserVO;
}
public void setEriporaSacUserVO(List<EriporaSacUserVO> eriporaSacUserVO) {
this.eriporaSacUserVO = eriporaSacUserVO;
}
public List<EriporaSacAccessVO> getEriporaSacAccessVO() {
return eriporaSacAccessVO;
}
public void setEriporaSacAccessVO(List<EriporaSacAccessVO> eriporaSacAccessVO) {
this.eriporaSacAccessVO = eriporaSacAccessVO;
}
}
答案 0 :(得分:1)
“这个错误[...]反复出现在特定记录中。”
您可以识别可重复显示此行为的特定记录。所以这应该很容易调试。但是,让我们为你取消它。
根据错误堆栈,您的更新语句是:
update PDOXDATA_GUSERPRO
set PROCESS=?, SYSTEM=?
where USER_NAME=?
您的约束PDOXDATA_GUSERPRO_N1
是(USER_NAME, SYSTEM, PROCESS)
上的复合唯一键。这些是更新语句中涉及的三列。 这不是巧合。
唯一复合键强制执行唯一排列。因此,我们可以为同一个PROCESS或同一个SYSTEM或同一个USER_NAME设置多个行。对于USER_NAME,SYSTEM,PROCESS的任何排列,我们都不能有多行。
所以,这是一个预测:当你传入一个有多个记录的USER_NAME时,更新失败。在这种情况下,您尝试为同一USER_NAME的多个实例设置相同的PROCESS和SYSTEM,这就是您获得唯一约束违规的原因。
现在我们可以看到你的代码很清楚@Hurds是正确的,你的Hibernate配置与你的物理数据模型不匹配。您已定义了一个列ID而不是所有三列:
@Id
@Column(name = "USER_NAME")
private String userName;
@Column(name = "SYSTEM")
private String system;
所以你可以选择:
如果您的数据库错误,则需要删除并重新创建约束。显然,这将需要管理现有数据以删除具有多个密钥实例的记录。
如果需要维护组合键,可以通过两种方法在Hibernate中配置它。 Check this other StackOverflow thread。