使用OpenJPA尝试批量删除时EntityExistsException

时间:2011-07-12 11:41:33

标签: jpa openjpa

我有三个类: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;
}

希望我复制了所有相关部分......任何人都可以提供帮助吗?

1 个答案:

答案 0 :(得分:1)

您没有正确阅读错误消息。它表示由于BorderPointLocation之间的外键约束而禁止删除。

如果您使用em.remove(location)删除Location,则级联删除会有效。在删除位置之前,使用您正在执行的删除查询不会自动删除BorderPoint

加载并使用em.remove删除它们,或者在删除BorderPoint之前执行其他删除查询。