Spring Data Repository does not delete ManyToOne Entity

前端 未结 6 623
陌清茗
陌清茗 2021-01-30 13:39

I\'m am currently trying to use a Spring Data repository to delete some of my entities. The delete call works without any exceptions/error messages, but the entity is not delete

相关标签:
6条回答
  • 2021-01-30 14:04

    The problem seems to be that you are using cascade=CascadeType.ALL, which also includes CascadeType.PERSIST. CascadeType.PERSIST means that the child entity is completely managed by the parent and you cannot delete it directly. In order to delete you just need to remove it from the parent.

    You could just add the other CascadeTypes instead of all. e.g CascadeType.REMOVE, if the only thing you would want is to remove the child if the parent is removed.

    0 讨论(0)
  • 2021-01-30 14:07

    What @user2936091 said is true but it doesn't solve the problem. I also had the exact same problem like you.

    The solution is to remove fetch=FetchType.EAGER from the parent class. Wen fetch type EAGER is used, the instance of board in the post object will have the

     private List<Post> posts = new ArrayList<Post>();
    

    populated because it was eagerly loaded, which means it still has a reference to itself, like @user2936091 mentions.

    My workaround to still load related properties eagerly was to create a DBService class and load the objects from there like this

    @Service
    public class DBService {
    
        BoardRepository boardRepo;
    
        @Transactional
        public Board getBoardProcess(Long id) {
           Board board = boardRepo.findById(id).get();
           board.getPosts().size(); // This will trigger the db query so that posts gets loaded
           // It needs to be done within a transactional so that the session is still the same to populate the fields. If it's done from outside of this method. It will not work
        }
    }
    
    0 讨论(0)
  • 2021-01-30 14:15

    cascade=CascadeType.PERSIST is used for updating insert in both side but for delete it will restrict.

    @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;
    
    0 讨论(0)
  • 2021-01-30 14:17

    A simple alternative:

    @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);
    
    }
    
    0 讨论(0)
  • 2021-01-30 14:20

    This is because you set mappedBy = "board" on Post class, doing so you tell that the master of Post is Board.

    0 讨论(0)
  • 2021-01-30 14:28

    Building on the excellent answer from user2936091 above, I just wanted to mention a (related) workaround I stumbled upon today: if the parent entity is not fetched into the Hibernate context, you are able to delete it directly.

    In my case this was achieved by setting fetch = FetchType.LAZY on the @ManyToOne relationship. I wanted this change for performance reasons anyway, and noticed that without the parent eagerly fetched Hibernate was free to delete it via the repository method call.

    0 讨论(0)
提交回复
热议问题