使用Hibernate删除特定表中的行(ManyToMany关系)

时间:2017-08-31 17:07:33

标签: java mysql hibernate spring-boot spring-data-jpa

我正在尝试在我的项目中创建一个关注/取消关注功能。以下函数似乎有效,但当我使用JpaRepository意图删除后续关系时,它只是从每个表中删除行:

Hibernate: delete from user_follow where follower=? Hibernate: delete from users_roles where users_id=? Hibernate: delete from user_follow where follower=? and following=? Hibernate: delete from users where id=?

我想在JpaRepository中为此创建一个取消关注方法和自定义查询,但我不知道如何包含'只有JPQL查询中的user_follow。

用户类:

package com.paulthemenace.blog.models;

import java.util.HashSet;
import java.util.Set;
import javax.persistence.*;

@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

@Column(length = 100)
private String fullName;

@Column(name = "username", nullable = false, length = 16, unique = true)
private String username;

@Column(length = 32)
private String password;

@OneToMany
private Set<Role> roles;

@OneToMany(mappedBy = "author")
private Set<Post> posts = new HashSet<Post>();

@Column
private String img;

@ManyToMany(mappedBy = "following")
private Set<User> follower;

@ManyToMany
@JoinTable(name = "user_follow", joinColumns = @JoinColumn(name = "follower"), inverseJoinColumns = @JoinColumn(name = "following"))
private Set<User> following;

public User() {
}

public User(String username, String password) {

    this.username = username;
    this.password = password;
}

@Override
public String toString() {
    return "User{" + "id=" + id + ", username='" + username + '\'' + ", passwordHash='" + password + '\''
            + ", fullName='" + fullName + '\'' + '}';
}

public Long getId() {
    return id;
}

public void setId(Long id) {
    this.id = id;
}

public String getFullName() {
    return fullName;
}

public void setFullName(String fullName) {
    this.fullName = fullName;
}

public String getUsername() {
    return username;
}

public void setUsername(String username) {
    this.username = username;
}

public String getPassword() {
    return password;
}

public void setPassword(String password) {
    this.password = password;
}

public String getImg() {
    return img;
}

public void setImg(String img) {
    this.img = img;
}

public Set<Post> getPosts() {
    return posts;
}

public void setPosts(Set<Post> posts) {
    this.posts = posts;
}

@ManyToMany
@JoinTable(name = "user_role", joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "role_id"))
public Set<Role> getRoles() {
    return roles;
}

public void setRoles(Set<Role> roles) {
    this.roles = roles;
}
public Set<User> getFollower() {
    return follower;
}

public void setFollower(Set<User> follower) {
    this.follower = follower;
}

public Set<User> getFollowing() {
    return following;
}

public void setFollowing(Set<User> following) {
    this.following = following;
}

}

控制器:

package com.paulthemenace.blog.controllers;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

import com.paulthemenace.blog.models.User;

import com.paulthemenace.blog.repositories.UserRepository;

@Controller
public class UserController {

@Autowired
private UserRepository userRepo;

@RequestMapping("/users/{username}")
public String userProfile(@PathVariable("username") String user, Model model) {

    Authentication auth = SecurityContextHolder.getContext().getAuthentication();

    String name = auth.getName();
    User currentUser = userRepo.findByUsername(name);

    model.addAttribute("currentUser", currentUser);
    System.out.println(currentUser);

    User foundUser = userRepo.findByUsername(user);
    model.addAttribute("user", foundUser);
    return "/users/profile";
}

@RequestMapping(value = "/users/follow/{username}")
public String follow(@PathVariable("username") String user, Model model) {

    Authentication auth = SecurityContextHolder.getContext().getAuthentication();

    String name = auth.getName();
    User currentUser = userRepo.findByUsername(name);

    model.addAttribute(currentUser);
    User foundUser = userRepo.findByUsername(user);

    currentUser.getFollowing().add(foundUser);
    model.addAttribute(foundUser);
    userRepo.save(foundUser);

    return "/users/profile";

}

@RequestMapping(value = "/users/unfollow/{username}")
public String unfollow(@PathVariable("username") String user, Model model) {
    Authentication auth = SecurityContextHolder.getContext().getAuthentication();
    User foundUser = userRepo.findByUsername(user);
    String currentUsername = auth.getName();
    User currentUser = userRepo.findByUsername(currentUsername);
    model.addAttribute(foundUser);
    model.addAttribute(currentUser);

    if (currentUser.getFollowing().contains(foundUser)) {
        currentUser.getFollowing().remove(foundUser);
        userRepo.delete(foundUser);
    }

    return "/users/profile";
}

}

UserRepository:

@Repository
public interface UserRepository extends JpaRepository<User, Long> {
User findByUsername(String username);

}

user_follow表:

CREATE TABLE `user_follow` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`follower` bigint(20) NOT NULL,
`following` bigint(20) NOT NULL,
`subscribed` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `follow_unique` (`follower`,`following`),
KEY `FK25l58y1y8ea2e93o068eqcpcs` (`following`),
CONSTRAINT `FK25l58y1y8ea2e93o068eqcpcs` FOREIGN KEY (`following`) 
REFERENCES `users` (`id`),
CONSTRAINT `FK4cnml690o1hgbjwnhywknu8rx` FOREIGN KEY (`follower`) REFERENCES 
`users` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=98 DEFAULT CHARSET=latin1

1 个答案:

答案 0 :(得分:0)

在这里您不应删除用户实体,而应对其进行更新或保存。

if (currentUser.getFollowing().contains(foundUser)) {
    currentUser.getFollowing().remove(foundUser);
    userRepo.save(foundUser);
}