我尝试更新数据库中的现有数据行,但我得到了这个例外:
[EL Warning]: 2012-10-24 20:02:27.798--UnitOfWork(22664464)--Exception [EclipseLink-4002] (Eclipse Persistence Services -
2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.DatabaseException Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '20-http://www.vilpra.lt/products/Foto/Aremikas/Katilas_zvake_big' for key 'PRIMARY' Error Code: 1062 Call: INSERT INTO x_links_media (image, link_id) VALUES (?, ?) bind => [2 parameters bound] Query: InsertObjectQuery(database.entity.XLinksMedia[ xLinksMediaPK=database.entity.XLinksMediaPK[ linkId=20, image=http://www.link.lt/products.jpg ] ])
主对象类看起来像下面的代码。关于OneToMany存在一些变量。
package database.entity;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.xml.bind.annotation.XmlRootElement;
@Entity
@Table(name = "x_parser_links")
@XmlRootElement
@NamedQueries({
@NamedQuery(name = "XParserLinks.findAll", query = "SELECT x FROM XParserLinks x"),
@NamedQuery(name = "XParserLinks.findByLinkId", query = "SELECT x FROM XParserLinks x WHERE x.linkId = :linkId"),
@NamedQuery(name = "XParserLinks.findByPageId", query = "SELECT x FROM XParserLinks x WHERE x.pageId = :pageId"),
@NamedQuery(name = "XParserLinks.findByLink", query = "SELECT x FROM XParserLinks x WHERE x.link = :link"),
@NamedQuery(name = "XParserLinks.findByLevel", query = "SELECT x FROM XParserLinks x WHERE x.level = :level"),
@NamedQuery(name = "XParserLinks.findByLinkType", query = "SELECT x FROM XParserLinks x WHERE x.linkType = :linkType"),
@NamedQuery(name = "XParserLinks.findByCreateDate", query = "SELECT x FROM XParserLinks x WHERE x.createDate = :createDate"),
@NamedQuery(name = "XParserLinks.findByDelDate", query = "SELECT x FROM XParserLinks x WHERE x.delDate = :delDate")})
public class XParserLinks implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "link_id")
private Integer linkId;
@Column(name = "page_id")
private Integer pageId;
@Column(name = "link")
private String link;
@Column(name = "level")
private Integer level;
@Column(name = "link_type")
private Short linkType;
@Column(name = "create_date")
@Temporal(TemporalType.TIMESTAMP)
private Date createDate;
@Column(name = "del_date")
@Temporal(TemporalType.TIMESTAMP)
private Date delDate;
@JoinColumn(name = "tev_link_id")
@OneToOne(cascade = CascadeType.ALL)
private XParserLinks tevas;
@OneToMany(mappedBy = "xParserLink", targetEntity = XLinksMedia.class, cascade = CascadeType.ALL)
private List<XLinksMedia> fotos;
@OneToMany(mappedBy = "xParserLink", targetEntity = XLinksVarchar.class, cascade = CascadeType.ALL)
private List<XLinksVarchar> atributes;
public XParserLinks() {
}
public XParserLinks(Integer linkId) {
this.linkId = linkId;
}
public Integer getLinkId() {
return linkId;
}
public void setLinkId(Integer linkId) {
this.linkId = linkId;
}
public Integer getPageId() {
return pageId;
}
public void setPageId(Integer pageId) {
this.pageId = pageId;
}
public String getLink() {
return link;
}
public void setLink(String link) {
this.link = link;
}
public Integer getLevel() {
return level;
}
public void setLevel(Integer level) {
this.level = level;
}
public Short getLinkType() {
return linkType;
}
public void setLinkType(Short linkType) {
this.linkType = linkType;
}
public Date getCreateDate() {
return createDate;
}
public void setCreateDate(Date createDate) {
this.createDate = createDate;
}
public Date getDelDate() {
return delDate;
}
public void setDelDate(Date delDate) {
this.delDate = delDate;
}
public XParserLinks getTevas() {
return tevas;
}
public void setTevas(XParserLinks tevas) {
this.tevas = tevas;
}
public List<XLinksMedia> getFotos() {
return fotos;
}
public void setFotos(List<XLinksMedia> fotos) {
this.fotos = fotos;
}
public List<XLinksVarchar> getAtributes() {
return atributes;
}
public void setAtributes(List<XLinksVarchar> atributes) {
this.atributes = atributes;
}
@Override
public int hashCode() {
int hash = 0;
hash += (linkId != null ? linkId.hashCode() : 0);
return hash;
}
@Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof XParserLinks)) {
return false;
}
XParserLinks other = (XParserLinks) object;
if ((this.linkId == null && other.linkId != null) || (this.linkId != null && !this.linkId.equals(other.linkId))) {
return false;
}
return true;
}
@Override
public String toString() {
return "database.entity.XParserLinks[ linkId=" + linkId + " ]";
}
}
这是我想要处理数据的代码。 XParserLinks
对象是man对象,就像上面的代码一样。在这个例子中,我检查对象是否没有他的主键LinkId然后用persist创建新对象,但是只更新对象和他的值,但是我想要更新现有对象之前就像我的意思一样异常。
XParserLinks e = entry.getValue();
if (e.getLinkId() == null) {
try {
TarpineManager.startTransaction();
TarpineManager.persist(e);
TarpineManager.commitTransaction();
} catch (Exception ex) {
ex.printStackTrace();
if (TarpineManager.getInstance().getTransaction().isActive()) {
TarpineManager.rollbackTransaction();
}
}
} else {
try {
TarpineManager.startTransaction();
TarpineManager.commitTransaction();
} catch (Exception ex) {
ex.printStackTrace();
if (TarpineManager.getInstance().getTransaction().isActive()) {
TarpineManager.rollbackTransaction();
}
}
}
答案 0 :(得分:0)
您是否有机会创建您的实体并通过武力设置其ID?我看到你的班上有一个setLinkId(Integer linkId)
方法。
首先,您应该使用merge
而不是persist
。现在,考虑到这一点,merge
方法也会抛出异常,因为JPA无法定义您要保留的实体是新实体还是普遍获取的实体,因为生命周期不一样。
如果您创建了一个对象并设置了它的id,那么该实体的状态为new
,但如果您在该实体应该具有detached
状态之前获取该实体。合并时,将正确更新分离的实体,但将保留新实体,并且由于获取了id,因此抛出异常。
您拥有实体的ID,因此您最好先获取它们,更新对象,然后再merge
。