【问题标题】:EntityExistsException When Attempting Bulk Delete With OpenJPA尝试使用 OpenJPA 进行批量删除时出现 EntityExistsException
【发布时间】:2011-07-12 11:41:33
【问题描述】:

我有三个类:Location、MTFCC 和 BorderPoint。

Location 与 MTFCC 具有单向 @ManyToOne 关系,该关系仅用作查找表。没有定义级联。

Location 还具有带 BorderPoint 的双向 @ManyToOne/@OneToMany。由于我希望在删除 Location 时删除所有关联的 BorderPoint 对象,因此我在关系的 Location 端设置了 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;
}

希望我复制了所有相关部分...有人可以帮忙吗?

【问题讨论】:

    标签: jpa openjpa


    【解决方案1】:

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

    如果您使用em.remove(location) 删除您的Location,级联删除将起作用。像您这样使用删除查询不会在删除位置之前自动删除 BorderPoints。

    要么加载它们并使用em.remove 删除它们,要么在删除BorderPoints 之前执行其他删除查询。

    【讨论】:

    • 谢谢...关于批量删除的文档并没有让我清楚。让我尝试一下并确保它有效,然后我会接受你的回答(可能需要我一天左右的时间)。
    • OpenJPA 击中了我的最后一根神经,我将它撕掉以支持休眠,但你绝对值得接受。感谢您的帮助!
    • @Jason:在这种情况下,Hibernate 将具有完全相同的行为。这是标准的 JPA。现在,您可能还有其他理由切换。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-13
    • 2011-08-08
    • 2010-09-21
    • 2020-07-09
    • 2015-11-25
    相关资源
    最近更新 更多