从系统中删除用户时遇到问题。变化的关键约束
Posted
技术标签:
【中文标题】从系统中删除用户时遇到问题。变化的关键约束【英文标题】:Having trouble deleting user from system. Volating key constraints 【发布时间】:2021-07-18 19:31:14 【问题描述】:每当我尝试从我的应用程序中删除用户时都会收到错误消息。
我的控制器方法:
@RequestMapping(value = "/delete/id", method = RequestMethod.GET)
@ResponseBody
public String deleteStudent(@PathVariable(name = "id") Long id)
userService.delete(id);
return "users";
我的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>
我的User.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】: @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 还包含级联删除,这将导致删除用户休眠的操作也会尝试删除角色。但其他用户可能已经拥有该角色。因此,您收到的异常。
你可以试试
@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) 但没有删除。
【讨论】:
感谢您的回复!我认为这可能有效,尽管现在每当我尝试登录系统ERROR: relation "user_table_roles" does not exist
时都会遇到不同的错误。这很奇怪,因为我没有使用该名称指定的表,只有表 user_role_table
。我不知道它为什么这样做
我通过删除我在测试时放置的@CollectionTable 来修复ERROR: relation "user_table_roles" does not exist
。我用你的方法级联,是的,这解决了我的问题。再次感谢您,我将您的回复标记为答案以上是关于从系统中删除用户时遇到问题。变化的关键约束的主要内容,如果未能解决你的问题,请参考以下文章
删除元素时使用 JoinTable 和 OrderColumn 的 Hibernate 单向 OneToMany 映射中的约束冲突