JPA - 如何级联删除引用自身的实体?

时间:2013-07-18 08:16:17

标签: java java-ee jpa

我有以下实体:

@Entity
@Table(name = "parameter_choice")
@NamedQueries({
        @NamedQuery(name = "listParameterChoicesByParameter",
                query = "SELECT pc FROM ParameterChoice pc WHERE pc.ParameterId = :parameterId")
})

@XmlRootElement
@Cacheable(false)
public class ParameterChoice implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "ParameterChoiceSequenceGenerator")
    @SequenceGenerator(allocationSize = 1, name = "ParameterChoiceSequenceGenerator", sequenceName = "parameter_choice_id_seq")
    @Column(nullable = false)
    private Integer id;

    @Column(name = "parameter_id", nullable = false)
    private Integer ParameterId;

    @Column(name = "parent_parameter_choice_id", nullable = true)
    private Integer parentParameterChoiceId;

    @OneToMany(fetch = FetchType.LAZY, orphanRemoval = true, cascade = CascadeType.REMOVE)
    @JoinColumn(name = "parent_parameter_choice_id", insertable = false, updatable = false)
    private List<ParameterChoice> parameterChoices;

    @Column(name = "canonical_name", nullable = false)
    private String canonicalName;

    @Column(name = "ui_only", nullable = false)
    private Boolean uiOnly;

然后我创建一个实体,然后创建第二个实体,其中第一个实体为parentParameterChoiceId。 当我尝试删除第一个实体时,我得到一个外键约束错误:

org.postgresql.util.PSQLException: ERROR: update or delete on table "parameter_choice" violates foreign key constraint "fk_parameter_choice_parameter_choice" on table "parameter_choice" Detail: Key (id)=(15) is still referenced from table "parameter_choice"

正如您所看到的,我尝试orphanRemoval = true, cascade = CascadeType.REMOVE但没有结果。有没有办法级联删除第一个Entity实例及其所有子实体?

修改 创建实体的代码:

@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@Path("/parameter-choice")
public String addParameterChoice(ParameterChoice parameterChoice) {
    String bodyContent = "";
    String errMessage = "Error in POST: /parameter-choice/.";
    try {
        em.persist(parameterChoice);
        bodyContent = mapper.writeValueAsString(parameterChoice);
        return responseBuilder.buildString(bodyContent, ResponseBuilder.OK);
    } catch (IOException e) {
        logger.log(Level.SEVERE, errMessage, e);
        return responseBuilder.buildString("errMessage", ResponseBuilder.ERROR);
    }
}

删除实体的代码:

@DELETE
@Produces(MediaType.APPLICATION_JSON)
@Path("/parameter-choice/{parameterChoiceId}")
public String deleteParameterChoice(@PathParam("parameterChoiceId") String parameterChoiceId) {
    String bodyContent = "OK";
    ParameterChoice parameterChoice = em.find(ParameterChoice.class, Integer.parseInt(parameterChoiceId));
    em.remove(parameterChoice);
    return responseBuilder.buildString(bodyContent, ResponseBuilder.OK);
}

1 个答案:

答案 0 :(得分:0)

正如JB Nizet在评论中指出的那样,我错过了允许级联删除似乎必要的ManyToOne关联:

@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.REMOVE)
@JoinColumn(name = "parent_parameter_choice_id", insertable = false, updatable = false)
private ParameterChoice parentParameterChoice;