有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java无法从系统中删除用户。旋转键约束

每当我试图从我的应用程序中删除一个用户时,就会出现一个错误

我的控制器方法

@RequestMapping(value = "/delete/{id}", method = RequestMethod.GET)
@ResponseBody
public String deleteStudent(@PathVariable(name = "id") Long id) {
    userService.delete(id);
    return "users";
}

我的用户。html

<!DOCTYPE html>
<html xmlns:th="http://www.w3.org/1999/xhtml">
<head>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
    <title>Users</title>
    <style>
        /*body,html {height:100%;overflow:hidden;}*/
        body {
            margin: 0;
            width: 100%;
            height: 100%;
            position: absolute;
        }

        .hero {
            position: relative;
            height: 100vh;
            width: 100%;
            display: flex;
            /*align-items: center;*/
            /*justify-content: center;*/
        }

        .hero::before {
            content: "";
            background-image: url(https://wallpaperaccess.com/full/3138960.jpg);
            background-size: cover;
            position: absolute;
            top: 0px;
            right: 0px;
            bottom: 0px;
            left: 0px;
            opacity: 0.5;
        }

        .content {
            position: relative;

        }

        .topnav {
            overflow: hidden;
            background-color: #333;
        }

        .topnav a {
            float: left;
            display: block;
            color: #f2f2f2;
            text-align: center;
            padding: 14px 16px;
            text-decoration: none;
            font-size: 17px;
        }

        .topnav a:hover {
            background-color: #ddd;
            color: black;
        }

        .topnav a.active {
            background-color: #4CAF50;
            color: white;
        }

        .topnav .icon {
            display: none;
        }

        @media screen and (max-width: 600px) {
            .topnav a:not(:first-child) {display: none;}
            .topnav a.icon {
                float: right;
                display: block;
            }
        }

        @media screen and (max-width: 600px) {
            .topnav.responsive {position: relative;}
            .topnav.responsive .icon {
                position: absolute;
                right: 0;
                top: 0;
            }
            .topnav.responsive a {
                float: none;
                display: block;
                text-align: left;
            }
        }
        table {
            border-collapse: separate;
        }

        th {
            background-color: #4287f5;
            color: white;
        }

        th,
        td {
            width: 150px;
            text-align: center;
            border: 1px solid black;
            padding: 5px;
        }
    </style>
</head>
<body>

<div class="topnav" id="myTopnav">
    <a th:href="@{/admin/adminIndex}" class="active">Home</a>
    <a th:href="@{/admin/users}">Users</a>
    <a th:href="@{/perform_logout}" >Logout</a>
    <a href="javascript:void(0);" class="icon" onclick="myFunction()">
        <i class="fa fa-bars"></i>
    </a>
</div>

<div class="hero">
    <div class="content">
        <div>
            <h1>Welcome to the users section</h1>
            <h2>List of users:</h2>

            <table>
                <tr>
                    <th>Id</th>
                    <th>Name</th>
                    <th>Username</th>
                    <th>Email</th>
                    <th>Role</th>
                    <th>Confirmed</th>
                    <th>Option</th>
                </tr>

                <tr th:each="User : ${userList}">
                    <td th:text="${User.id}">Id</td>
                    <td th:text="${User.name}">Name</td>
                    <td th:text="${User.username}">Username</td>
                    <td th:text="${User.email}">Email</td>
                    <td th:text="${User.roles}">Role</td>
                    <td th:text="${User.confirmed}">Confirmed</td>
                    <td>
<!--                        <a th:href="|@{/delete/${User.id}}|" onclick="return confirm('Are you sure?')">Delete</a>-->
                        <a th:href="@{delete/__${User.id}__}" class="btn btn-danger">Delete</a>
                    </td>
                </tr>
            </table>
        </div>
    </div>
</div>

<script>
    function myFunction() {
        var x = document.getElementById("myTopnav");
        if (x.className === "topnav") {
            x.className += " responsive";
        } else {
            x.className = "topnav";
        }
    }
</script>

<script type="text/javascript">
    $(function(){
        var $page = jQuery.url.attr("file");
        $('ul.navigation li a').each(function(){
            var $href = $(this).attr('href');
            if ( ($href == $page) || ($href == '') ) {
                $(this).addClass('on');
            } else {
                $(this).removeClass('on');
            }
        });
    });
</script>

</body>
</html>

我的用户。java

package com.lukas.ramonas.cms.Model;

import com.lukas.ramonas.cms.Validators.ValidEmail;

import javax.persistence.*;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;

/*******************************************
 * Defined user model
 *******************************************/
@Entity
@Table(name = "user_table", schema = "public")
public class User {

    @Id
    @Column(name = "user_id")
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long user_id;

    @Column(name = "name")
    private String name;

    @Column(name = "username")
    private String username;

    @Column(name = "password")
    private String password;

    @Column(name = "email")
    private String email;

    @Column(name = "confirmed")
    private boolean confirmed;

    @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    @JoinTable(
            name = "user_role_table",
            joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "user_id"),
            inverseJoinColumns = @JoinColumn(name = "role_id", referencedColumnName = "role_id"))
    private Collection<Role> roles = new HashSet<>();



/*******************************************
* Setters and getters
*******************************************/

    public Long getId() {
        return user_id;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

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

    public String getUsername() {
        return username;
    }

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

    public String getPassword() {
        return password;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getEmail() {
        return email;
    }

    public void setConfirmed(Boolean confirmed) {
        this.confirmed = confirmed;
    }

    public Boolean getConfirmed() {
        return confirmed;
    }

    public void setRoles(Collection roles) {
        this.roles = roles;
    }

    public Collection<Role> getRoles() { return this.roles;
    }
}

错误

org.postgresql.util.PSQLException: ERROR: update or delete on table "privilege_table" violates foreign key constraint "role_privilege_table_privilege_id_fkey" on table "role_privilege_table"
  Detail: Key (privilege_id)=(1) is still referenced from table "role_privilege_table".

    at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2532) ~[postgresql-42.2.14.jar:42.2.14]
    at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2267) ~[postgresql-42.2.14.jar:42.2.14]
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:312) ~[postgresql-42.2.14.jar:42.2.14]
    at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:448) ~[postgresql-42.2.14.jar:42.2.14]
    at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:369) ~[postgresql-42.2.14.jar:42.2.14]
    at org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:153) ~[postgresql-42.2.14.jar:42.2.14]
    ...

从这个错误中,我假设每当我删除一个用户时,一个特权表实例也因为某种原因试图被删除。我在网上查看过是否有其他人也有同样的问题,我发现this thread没有给我带来任何好的结果

任何提示或帮助都非常感谢


共 (1) 个答案

  1. # 1 楼答案

     @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
        @JoinTable(
                name = "user_role_table",
                joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "user_id"),
                inverseJoinColumns = @JoinColumn(name = "role_id", referencedColumnName = "role_id"))
        private Collection<Role> roles = new HashSet<>();
    

    这里您使用@ManyToMany。这意味着一个用户可以有多个角色,但也意味着一个角色属于多个用户

    由于其他用户也可以与同一角色有关系,因此您不能在该关系上有CascadeType.ALL。All还包含cascade remove,这将导致删除用户的操作hibernate也将尝试删除该角色。但其他用户可能已经有了这个角色。因此,您将收到例外情况

    你可以尝试使用

     @ManyToMany(cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.DETACH} , fetch = FetchType.EAGER)
       @JoinTable(
                    name = "user_role_table",
                    joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "user_id"),
                    inverseJoinColumns = @JoinColumn(name = "role_id", referencedColumnName = "role_id"))
            private Collection<Role> roles = new HashSet<>();
    

    哪一个最接近您使用的(CascadeType.ALL),但没有删除