我有三个类:Location,MTFCC和BorderPoint。
Location与MTFCC具有单向@ManyToOne关系,该关系仅用作Lookup表。没有定义级联。
位置还有一个带BorderPoint的双向@ ManyToOne / @ OneToMany。由于我希望在删除位置时删除所有关联的BorderPoint对象,因此我在关系的位置侧设置了cascadetype.ALL。
不幸的是,当我尝试删除某个位置时,会抛出EntityExistsException:
org.apache.openjpa.persistence.EntityExistsException: Cannot delete or update
a parent row: a foreign key constraint fails (`mapmaker`.`BORDERPOINT`,
CONSTRAINT `BORDERPOINT_ibfk_1` FOREIGN KEY (`LOCATIONID`) REFERENCES `LOCATION`
(`LOCATIONID`)) {prepstmnt 21576566 DELETE t0, t1 FROM LOCATION t0 INNER JOIN
MTFCC t1 ON t0.MTFCCID = t1.MTFCCID WHERE (t0.STATEFP = ? AND t1.MTFCCCODE = ?)
[params=?, ?]} [code=1451, state=23000]
[ERROR] FailedObject: DELETE t0, t1 FROM LOCATION t0 INNER JOIN MTFCC t1 ON
t0.MTFCCID = t1.MTFCCID WHERE (t0.STATEFP = ? AND t1.MTFCCCODE = ?)
[java.lang.String]
看起来它正在尝试删除我不想发生的相关MTFCC对象。但是,我希望删除关联的BorderPoint对象。
这是代码(砍掉一点):
@SuppressWarnings("unused")
@Entity
@Table(name="LOCATION")
@DetachedState(enabled=true)
public class Location implements Serializable, IsSerializable, Cloneable {
private Long id;
private String stateGeoId;
private MTFCC mtfcc;
private List<BorderPoint> borderPointList;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="LOCATIONID")
public Long getId() {
return id;
}
@ManyToOne
@JoinColumn(name="MTFCCID")
public MTFCC getMtfcc() {
return mtfcc;
}
@OneToMany(cascade = CascadeType.ALL, mappedBy = "location", fetch = FetchType.EAGER)
public List<BorderPoint> getBorderPointList() {
return borderPointList;
}
}
@Entity
@Table(name = "BORDERPOINT")
@DetachedState(enabled = true)
public class BorderPoint implements Serializable, IsSerializable {
private Long id;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="BORDERID")
public Long getId() {
return id;
}
@ManyToOne(targetEntity = Location.class)
@JoinColumn(name="LOCATIONID")
public Location getLocation() {
return location;
}
}
@Entity
@Table(name = "MTFCC")
public class MTFCC implements Serializable, IsSerializable {
private Long id;
private String mtfccCode;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "MTFCCID")
public Long getId() {
return id;
}
// etc
}
并且,为了更好的衡量,这里是删除代码:
@Override
@Transactional
public int removeByStateGeoIdAndMtfcc(String stateGeoId, String mtfccCode) throws RepositoryException {
EntityManager em = entityManagerFactory.createEntityManager();
String jpaQuery = "DELETE FROM Location L where L.stateFP = ?1 AND L.mtfcc.mtfccCode = ?2";
int affectedRows = 0;
Query query = em.createQuery(jpaQuery).setParameter(1, stateGeoId).setParameter(2, mtfccCode);
try {
em.getTransaction().begin();
affectedRows = query.executeUpdate();
em.getTransaction().commit();
} catch (Exception e) {
//log.debug("Exception: ", e);
throw new RepositoryException(e);
}
em.close();
return affectedRows;
}
希望我复制了所有相关部分......任何人都可以提供帮助吗?
答案 0 :(得分:1)
您没有正确阅读错误消息。它表示由于BorderPoint
和Location
之间的外键约束而禁止删除。
如果您使用em.remove(location)
删除Location
,则级联删除会有效。在删除位置之前,使用您正在执行的删除查询不会自动删除BorderPoint
。
加载并使用em.remove
删除它们,或者在删除BorderPoint
之前执行其他删除查询。