简体   繁体   English

删除实体@OneToMany @ManyToOne。 键仍然从表中引用

[英]Deleting Entities @OneToMany @ManyToOne. Key is still referenced from table

I have two entities - User and Song :我有两个实体 - UserSong

User.class:用户.class:

@Entity
@Table(name = "users")
public class User {
    
   @Id
   @Column(name = "user_id")
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   private Long id;
    
   @Column(name = "first_name")
   private String firstName;
    
   @Column(name = "last_name")
   private String lastName;
    
   @Column(name = "login",unique = true)
   private String login;
    
   @Column(name = "password")
   private String password;
    
   @Column(name = "token")
   private UUID token;
    
   @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
   @JoinTable(
      name = "users_songs",
      joinColumns = @JoinColumn(
         name = "u_id",
         referencedColumnName = "user_id"
      ),
      inverseJoinColumns = @JoinColumn(
         name = "s_id",
         referencedColumnName = "song_id"
      )
   )
   private List<Song> songs = new ArrayList<>();
}

Song.class:歌曲.class:

@Entity
@Table(name = "songs")
public class Song {
        
   @Id
   @Column(name = "song_id")
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   private Long id;
        
   @Column(name = "song_title")
   private String songTitle;
        
   @Column(name = "composer_name")
   @ElementCollection(fetch = FetchType.EAGER)
   @CollectionTable(name = "composers")
   @OnDelete(action = OnDeleteAction.CASCADE)
   @JoinColumn(name = "composer_id")
   private Set<String> composer;
        
   @Column(name = "author_of_words_name")
   @ElementCollection(fetch = FetchType.EAGER)
   @CollectionTable(name = "author_of_words")
   @OnDelete(action = OnDeleteAction.CASCADE)
   @JoinColumn(name = "authorOfWords_id")
   private Set<String> authorOfWords;
        
   @Column(name = "song_artist")
   private String songArtist;
        
   @Column(name = "song_timing")
   private int songTiming;
        
   @ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH})
   @JoinColumn(name = "user_id_key")
   private User user;
        
   @Column(name = "rate_value")
   @ElementCollection(fetch = FetchType.EAGER)
   @CollectionTable(name = "rating")
   @MapKeyColumn(name = "login")
   @OnDelete(action = OnDeleteAction.CASCADE)
   @JoinColumn
   private final Map<String, Integer> rating = new HashMap<>();
        
   @Column
   @ElementCollection(fetch = FetchType.EAGER)
   @CollectionTable(name = "comment")
   @MapKeyColumn(name = "login")
   @OnDelete(action = OnDeleteAction.CASCADE)
   @JoinColumn
   private final Map<String, String> comments = new HashMap<>();
}

I want to delete a Song, but not delete a User.我想删除一首歌曲,但不删除一个用户。

I tried deleting it like this:我试着像这样删除它:

Query query = session.createQuery("DELETE Song s WHERE s.user = :user AND s.songTitle = :songTitle");
query.setParameter("user", user);
query.setParameter("songTitle", songTitle);
query.executeUpdate()

But the error drops:但错误下降:

    Caused by: org.hibernate.exception.ConstraintViolationException: could not execute statement...
    Caused by: org.postgresql.util.PSQLException: ERROR: update or delete on table "songs" violates foreign key constraint "fka7me64vk6jtx81wt2ggbvm6ur" on table "users_songs"
     Key (song_id)=(28) is still referenced from table "users_songs".

I understand that the problem is due to the fact that in the spanning table users_songs , which occurred due to the connection @OneToMany .我知道问题是由于在生成表users_songs中,这是由于连接@OneToMany而发生的。

I read a similar question in the STO and it says that you need to break the connection.我在 STO 中阅读了一个类似的问题,它说您需要断开连接。 how to delete the record from the join table in hibernate 如何从 hibernate 中的连接表中删除记录

I executed the following code:我执行了以下代码:

List<Song> collect = user.getSongs().stream().filter(s -> !s.getSongTitle().equals(songTitle)).collect(Collectors.toList());
user.setSongs(collect);
session.update(user);
Query query = session.createQuery("DELETE Song s WHERE s.songTitle = :songTitle");
query.setParameter("songTitle", songTitle);
query.executeUpdate();

This code works, but I don't think it's quite right.这段代码有效,但我认为它不太正确。 Now the question.现在的问题。 How do I delete a Song from a user?如何删除用户的歌曲? With the condition that the song should not cascade to delete the user.条件是歌曲不应该级联删除用户。

Please help me solve this issue correctly.请帮我正确解决这个问题。 I'd really appreciate it.我真的很感激。

You can specify ON DELETE CASCADE for the foreign key constraint fka7me64vk6jtx81wt2ggbvm6ur on the table users_songs like below:您可以为表users_songs上的外键约束fka7me64vk6jtx81wt2ggbvm6ur指定ON DELETE CASCADE ,如下所示:

@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinTable(
   name = "users_songs",
   joinColumns = @JoinColumn(
      name = "u_id",
      referencedColumnName = "user_id"
   ),
   inverseJoinColumns = @JoinColumn(
      name = "s_id",
      referencedColumnName = "song_id"
   ),
   inverseForeignKey = @ForeignKey(
      name = "users_songs_songs_FK",  // fka7me64vk6jtx81wt2ggbvm6ur renamed to users_songs_songs_FK
      foreignKeyDefinition = "FOREIGN KEY (s_id) REFERENCES songs(song_id) ON DELETE CASCADE"
   )
)
private List<Song> songs = new ArrayList<>();

and after database schema regeneration your initial query should work as expected.并且在数据库模式重新生成后,您的初始查询应该按预期工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 具有复合键的JPA OneToMany和ManyToOne正在生成第三个表 - JPA OneToMany and ManyToOne with a composite key is generating a third table Hibernate 级联删除依赖实体 (ManyToOne OneToMany) - Hibernate cascade delete dependent entities (ManyToOne OneToMany) ManyToOne OneToMany 双向:从参考表中检索数据 - ManyToOne OneToMany bi-direction: Retrieve data from reference table OneToMany 和 ManyToOne 实体对象以递归方式链接 - OneToMany and ManyToOne entities objects are linked in recursion @ManyToOne @OneToMany 映射,外键为 null - @ManyToOne @OneToMany Mapping , foreign key is null 在关系ManyToOne上加入时出错。 使用QueryDSL - Error in Join on a relation ManyToOne. Using QueryDSL 映射到子表两次 - @OneToMany和@ManyToOne - Mapping to a child table twice - @OneToMany & @ManyToOne 无法使用 OneToMany 和 ManyToOne 关系在 hibernate 中创建表(也无法创建外键) - Unable to create a table in hibernate using OneToMany and ManyToOne relationship(also unable to create Foreign Key) 将带有@ManyToOne的子实体删除到其他实体时,出现NullPointerException - NullPointerException when deleting subentity with @ManyToOne to other Entities JPA 检索所有引用的关系(ManyToMany - ManyToOne - OneToMany) - JPA all referenced relations are retrieved (ManyToMany - ManyToOne - OneToMany)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM