Подтвердить что ты не робот

Spring Хранилище данных не удаляет объект ManyToOne

В настоящее время я пытаюсь использовать репозиторий данных Spring для удаления некоторых моих объектов. Вызов удаления работает без сообщений об исключениях/ошибках, но после этого объект не удаляется.

Это мои сущности:

public class Board implements Serializable {

    @Id
    @GeneratedValue(generator = "uuid2")
    @GenericGenerator(name = "uuid2", strategy = "uuid2")
    @Column(columnDefinition = "BINARY(16)")
    private UUID uuid;

    @OneToMany(fetch=FetchType.EAGER, cascade=CascadeType.ALL, orphanRemoval = true, mappedBy = "board")
    private List<Post> posts = new ArrayList<Post>();
}

и

public class Post implements Serializable {

    @Id
    @GeneratedValue
    private long id;

    @ManyToOne(optional = false)
    @JoinColumn(name="board_uuid", updatable = false, nullable = false)
    @JsonBackReference
    private Board board;
}

Репозиторий настолько прост, насколько это возможно:

@Repository
public interface PostRepository extends CrudRepository<Post, Long> {
}

Вызов удаления - это что-то вроде

postRepository.delete(50);

Любые идеи, почему это изменение не отражено в базе данных?

Изменить 1:

Я нашел обходное решение, но я до сих пор не понимаю, что такое настоящая проблема. Он "работает", если я удаляю сообщение вроде этого (есть несколько исключений из-за ограничений ограничений, но все равно сообщение удаляется):

post.setBoard(null);
postRepo.delete(post);

Изменить 2:

Когда я смотрю на выполняемые SQL-запросы, я вижу, что спящий режим даже не пытается удалить. Единственное, что происходит, это те два оператора select:

Hibernate: select post0_.id as id1_1_0_, post0_.board_uuid as board_uu6_1_0_, post0_.content as content2_1_0_, post0_.x as x3_1_0_, post0_.y as y4_1_0_, post0_.z as z5_1_0_, board1_.uuid as uuid1_0_1_ from Post post0_ left outer join Board board1_ on post0_.board_uuid=board1_.uuid where post0_.id=?
Hibernate: select posts0_.board_uuid as board_uu6_0_0_, posts0_.id as id1_1_0_, posts0_.id as id1_1_1_, posts0_.board_uuid as board_uu6_1_1_, posts0_.content as content2_1_1_, posts0_.x as x3_1_1_, posts0_.y as y4_1_1_, posts0_.z as z5_1_1_ from Post posts0_ where posts0_.board_uuid=?

Изменить 3

Выключает каскад = CascadeType.ALL на сообщениях, кажется, проблема. Без него удаление отлично работает (но сейчас я пропускаю каскад изменений в сообщениях)

4b9b3361

Ответ 1

Проблема заключается в том, что вы используете cascade=CascadeType.ALL, который также включает CascadeType.PERSIST. CascadeType.PERSIST означает, что дочерний объект полностью управляется родителем, и вы не можете удалить его напрямую. Для удаления вам просто нужно удалить его из родителя.

Вы можете просто добавить другой CascadeTypes вместо всех. например CascadeType.REMOVE, если единственное, что вы захотите, это удалить дочерний элемент, если родитель удален.

Ответ 2

Основываясь на отличном ответе от user2936091 выше, я просто хотел упомянуть (связанное) обходное решение, которое я наткнулся на сегодняшний день: если родительский объект не загружается в контекст Hibernate, вы можете удалить его напрямую.

В моем случае это было достигнуто установкой fetch = FetchType.LAZY в отношении @ManyToOne. В любом случае, я хотел это изменение по причинам производительности, и заметил, что без родительского желаемого Hibernate было бы свободно удалять его с помощью вызова метода репозитория.

Ответ 3

Это связано с тем, что вы устанавливаете mappedBy = "board" в классе Post, делая это, чтобы сообщить, что хозяин Post - это Board.

Ответ 4

Простая альтернатива:

@Repository
public interface PostRepository extends CrudRepository<Post, Long> {

@Modifying(clearAutomatically = true, flushAutomatically = true)
@Query(value = "DELETE FROM post WHERE id = ?1", nativeQuery = true)
void deleteById(long postId);

}

Ответ 5

cascade = CascadeType.PERSIST используется для обновления вставки в обе стороны, но для удаления это ограничит.

@ManyToOne(cascade=CascadeType.PERSIST, fetch = FetchType.LAZY)
//  @JoinColumn(name = "qid")
    @JoinColumn(name = "qid", referencedColumnName = "qid", foreignKey = @ForeignKey(name = "qid"), nullable = false)
    // @JsonIgnore
    @JsonBackReference
    private QueueGroup queueGroup;