При удалении сущности JPA, содержащей @CollectionOfElements, создается исключение ConstraintViolationException - PullRequest
2 голосов
/ 16 июня 2010

Я пытаюсь удалить объекты, содержащие списки Integer, и получаю ConstraintViolationExceptions из-за внешнего ключа в таблице, созданной для хранения целых чисел. Похоже, что удаление не каскадно сопоставляется с коллекцией.

Я провел немало поисков, но все примеры, которые я видел, как это сделать, относятся к сопоставленной коллекции других сущностей, которые можно аннотировать; здесь я просто храню список Integer. Вот соответствующая выдержка из класса, который я храню:

@Entity
@Table(name="CHANGE_IDS")
@GenericGenerator(
        name = "CHANGE_ID_GEN",
        strategy =  "org.hibernate.id.enhanced.SequenceStyleGenerator",
        parameters = {
                @Parameter(name="sequence_name", value="course_changes_seq"),
                @Parameter(name="increment_size", value="5000"),
                @Parameter(name=" optimizer", value="pooled")
                     }
    )
@NamedQueries ({
    @NamedQuery(
        name="Changes.getByStatus",
        query=  "SELECT c " +
                "FROM DChanges c " +
                "WHERE c.status = :status "),
    @NamedQuery(
            name="Changes.deleteByStatus",
            query=  "DELETE " +
                    "FROM Changes c " +
                    "WHERE c.status = :status ")
})
public class Changes {
    @Id
    @GeneratedValue(generator="CHANGE_ID_GEN")
    @Column(name = "ID")
    private final long id;

    @Enumerated(EnumType.STRING)
    @Column(name = "STATUS", length = 20, nullable = false)
    private final Status status;

    @Column(name="DOC_ID")
    @org.hibernate.annotations.CollectionOfElements
    @org.hibernate.annotations.IndexColumn(name="DOC_ID_ORDER")
    private List<Integer> docIds;
}

Я удаляю объекты Changes с помощью @NamedQuery:

final Query deleteQuery = this.entityManager.createNamedQuery("Changes.deleteByStatus");
deleteQuery.setParameter("status", Status.POST_FLIP);
final int deleted = deleteQuery.executeUpdate();
this.logger.info("Deleted " + deleted + " POST_FLIP Changes");

Ответы [ 2 ]

2 голосов
/ 17 июня 2010

Удаление HQL не распространяется на связанные сущности в соответствии со спецификациями JPA (хотя некоторые пользователи хотели бы иметь расширенное поведение, описанное в HHH-695 ). Из спецификации JPA 1.0:

4.10 Операции массового обновления и удаления

(...)

Операция удаления применяется только к сущности указанного класса и его подклассы. Это не каскад связанные лица.

(...)

Таким образом, вы можете самостоятельно использовать массовое удаление.

Однако, в частном случае CollectionOfElements, которые не являются сущностями (и поскольку нет способа массового удаления таблицы для коллекции), я ожидал, что сработает следующее:

@Column(name="DOC_ID")
@org.hibernate.annotations.CollectionOfElements
@org.hibernate.annotations.IndexColumn(name="DOC_ID_ORDER")
@OnDelete(action = OnDeleteAction.CASCADE)
private List<Integer> docIds;

Но, к сожалению, это не так, SessionFactory жалуется:

org.hibernate.MappingException: only inverse one-to-many associations may use on-delete="cascade": com.stackoverflow.q3049451.Changes.docIds

Согласно этой теме , это звучит как ошибка ...

Таким образом, это оставляет вас с решением, которое вы реализовали: выполнить выбор, цикл и удалить объекты.

0 голосов
/ 17 июня 2010

После долгих экспериментов я обнаружил, что использование именованного запроса Changes.deleteByStatus , показанного в вопросе, просто не приведет к каскадному удалению удаления в таблицу сбора независимо от того, какую комбинацию аннотаций я пробовал.

В итоге я получил все совпадающие сущности с именованным запросом Changes.getByStatus , а затем удалил их через менеджер сущностей, который, кажется, правильно обрабатывает каскад.

    final Query query = this.entityManager.createNamedQuery("Changes.getById");
    query.setParameter("status", Status.POST_FLIP);
    List<Changes> changes = query.getResultList();
    for (Changes change : changes) {
        this.entityManager.remove(change);
    }

Любые другие объяснения или предложения приветствуются.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...