gpt4 book ai didi

java - Spring Security中错误的自定义设计用户/权限

转载 作者:行者123 更新时间:2023-12-01 10:44:06 27 4
gpt4 key购买 nike

我认为我的用户和权限设计存在弱点。登录工作正常,但我的 create_user 页面上有一个 org.hibernate.TransientPropertyValueException

当我从表单添加新用户时,使用以下代码:

public fr.cnamts.navigo.domain.User create(UserCreateForm form) {
fr.cnamts.navigo.domain.User user = new fr.cnamts.navigo.domain.User();
user.setUsername(form.getEmail());
user.setPassword(new BCryptPasswordEncoder().encode(form.getPassword()));
user.setEnabled(true);

Authorities role = new Authorities();
role.setUser(user);
role.setAuthority(form.getRole());

role = authoritiesRepository.save(role);
user.addAuthorities(role);

user = userRepository.save(user);
return user;
}

save(role) 上出现 org.hibernate.TransientPropertyValueException。权限类:

@Entity
@Table(name="authorities", uniqueConstraints = @UniqueConstraint(
columnNames = { "authority", "username" }))
public class Authorities {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "authority_id",
unique = true, nullable = false)
private Integer id;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "username", nullable = false)
private User user;

@Column(name = "authority", nullable = false, length = 45)
private String authority;

public Authorities() {
}

public Authorities(User user, String role) {
this.user = user;
this.authority = role;
}

public void setUser(User user) {
this.user = user;
if (!user.getAuthorities().contains(this)) { // warning this may cause performance issues if you have a large data set since this operation is O(n)
user.getAuthorities().add(this);
}
} // assume other basic getters and setters

用户一:

@Entity
@Table(name = "users")
public class User {
@Id
@Column(name = "username", nullable = false, unique = true, length = 60)
private String username;

@Column(name = "password", nullable = false, length = 60)
private String password;

@Column(name = "enabled", nullable = false)
private boolean enabled;

// private boolean tokenExpired;

@OneToMany(fetch = FetchType.LAZY, mappedBy = "user")
private Set<Authorities> authorities;

public User() {
this.authorities = new HashSet<Authorities>();
}

public User(String username, String password, boolean enabled) {
this.username = username;
this.password = password;
this.enabled = enabled;
this.authorities = new HashSet<Authorities>();
}

public User(String username, String password, boolean enabled,
Set<Authorities> userRoles) {
this.username = username;
this.password = password;
this.enabled = enabled;
if (userRoles != null) {
this.authorities = userRoles;
} else {
this.authorities = new HashSet<Authorities>();
}
}

public void addAuthorities(Authorities role) {
this.authorities.add(role);
if (role.getUser() != this) {
role.setUser(this);
}
}

public void addAuthorities(String role, User user) {
this.addAuthorities(new Authorities(user, role));
}

当我添加新用户时,我需要用户的角色/权限,但要创建权限对象,我需要用户实例。

这是控制台跟踪的摘录:

Hibernate: select user0_.username as username1_1_, user0_.enabled as enabled2_1_, user0_.password as password3_1_ from users user0_ where user0_.username=?
Hibernate: select nextval ('hibernate_sequence')
Hibernate: select user_.username, user_.enabled as enabled2_1_, user_.password as password3_1_ from users user_ where user_.username=?
2015-12-15 16:21:26.390 WARN 6832 --- [nio-8081-exec-3] o.h.a.i.UnresolvedEntityInsertActions : HHH000437: Attempting to save one or more entities that have a non-nullable association with an unsaved transient entity. The unsaved transient entity must be saved in an operation prior to saving these dependent entities.
Unsaved transient entity: ([fr.cnamts.navigo.domain.User#datm.flux1@cnamts.fr])
Dependent entities: ([[fr.cnamts.navigo.domain.Authorities#4]])
Non-nullable association(s): ([fr.cnamts.navigo.domain.Authorities.user])
2015-12-15 16:21:26.398 ERROR 6832 --- [nio-8081-exec-3] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.TransientPropertyValueException: Not-null property references a transient value - transient instance must be saved before current operation : fr.cnamts.navigo.domain.Authorities.user -> fr.cnamts.navigo.domain.User; nested exception is java.lang.IllegalStateException: org.hibernate.TransientPropertyValueException: Not-null property references a transient value - transient instance must be saved before current operation : fr.cnamts.navigo.domain.Authorities.user -> fr.cnamts.navigo.domain.User] with root cause

org.hibernate.TransientPropertyValueException: Not-null property references a transient value - transient instance must be saved before current operation : fr.cnamts.navigo.domain.Authorities.user -> fr.cnamts.navigo.domain.User
at org.hibernate.action.internal.UnresolvedEntityInsertActions.checkNoUnresolvedActionsAfterOperation(UnresolvedEntityInsertActions.java:137) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]

我认为我在 getter/setter 端或构造函数端缺少一些东西。数据库端的对象看起来不错。这是创建代码(postgresql):

create table users ( 
username varchar(50) primary key,
password varchar(255) not null,
enabled boolean not null DEFAULT TRUE
);


create table authorities (
authority_id SERIAL,
username varchar(50) not null,
authority varchar(50) not null,
PRIMARY KEY (authority_id),
CONSTRAINT uni_username_authority UNIQUE(authority,username),
constraint fk_roles_users foreign key (username) references users (username)
);

最佳答案

由于权限表具有用户表的外键,因此用户必须在权限之前保存。

通过将级联注释添加到关联中,您可以让 Hibernate 在持久化 Authority 之前持久化关联的 User:

@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "username", nullable = false)
private User user;

https://docs.oracle.com/javaee/5/api/javax/persistence/ManyToOne.html

关于java - Spring Security中错误的自定义设计用户/权限,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34293459/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com