Pergunta

Eu tenho 2 EJB 3 Entity Beans:

@Entity
public class Organisation
{
    @Id
    @Column(length = 64)
    private String guid;

    private String name;

    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.REMOVE)
    @JoinColumn(name = "home_unit_fk", nullable = true)
    private Unit homeUnit;          
}

@Entity
public class Unit
{
    @Id
    @Column(length = 64)
    private String guid;

    private String name;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "organisation_fk", nullable = false)
    private Organisation organisation;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "parent_unit_fk", nullable = true)
    private Unit parentUnit;

    @OneToMany(mappedBy = "parentUnit", fetch = FetchType.LAZY, cascade = CascadeType.REMOVE)
    @OrderBy("shortName")
    @OptimisticLock(excluded = true)
    private Set<Unit> childUnits;   
}

Se eu fizer uma exclusão na organização usando Dao padrão:

public int deleteByGuid(final String guid) 
{
    final Query query = entityManager.createQuery("delete from " + getPersistentClass().getName() + " where guid = :guid");
    query.setParameter("guid", guid);
    return query.executeUpdate();
}

Mas eu recebo a seguinte exceção:

com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Não é possível excluir ou atualizar uma linha pai: a restrição de chave estrangeira falhar (config.unit, CONSTRAINT FK27D184F5D4393D FOREIGN KEY (organisation_fk) Referências organisation (guid))

Eu não entendo. O que estou fazendo de errado? JPA / Hibernate não deve executar exclusões em ambos da Unidade e da Organização dentro da mesma transação?

Foi útil?

Solução

A consulta de exclusão em massa não carregar objetos na memória e ignora qualquer cascata especificado em associações.

Gostaria de codificar seu método de exclusão como:

public int deleteByGuid(final String guid){
    Organization org = entityManager.find(Organization.class, guid);
    entityManager.remove(org);
}

Se você usar uma consulta para fazer atualizações em massa, a operação é delegada ao banco de dados diretamente. Se você deseja excluir objetos filho, você tem que definir um gatilho DELETE CASCADE no nível de "banco de dados".

Ao carregar o objecto e a sua remoção, hibernação irá desencadear a cascata no nível "objecto".

Mais informações disponíveis em: http://twasink.net/blog/2005/04/differences-in-behaviour-between-hibernate-delete-queries-and-the-old-way/

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top