已通过 Spring-Sequrity 进行授权。@Transient
在用户实体中,我对密码验证字段使用注释(代码如下)。该字段最终不会出现在数据库中,但是如果您从存储库中提取该对象,则该字段会出现在那里,这尤其会阻止通过 userRepo.save(userEntity) 进一步保存它:会发生异常:org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Error while committing the transaction
我尝试研究这个问题,是的,事实证明这是正常行为@Transient
。建议显式指示注释@Transient
来源@javax.persistence.Transient
并@org.springframework.data.annotation.Transient
没有帮助,就像声明字段时的瞬态关键字一样。
关于如何防止字段进入private String password2;
实体存储库的任何想法,以便您可以轻松地使用(例如)保存从存储库中获取的该实体?
public String setOnlineData(String username) {
UserEntity userEntity = userRepo.findByUsername(username);
userEntity.setOnlineDate(LocalDateTime.now());
userRepo.save(userEntity); ///exception
return "Successfully";
}
@Entity
@Table(name = "t_user")
@Getter
@Setter
public class UserEntity implements UserDetails {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@NotBlank(message = "Имя пользователя не может быть пустым!")
private String username;
@NotBlank(message = "Пароль не может быть пустым!")
private String password;
@Transient
@NotBlank(message = "Пароль не может быть пустым!")
private String password2;
private boolean active;
private LocalDateTime regDate;
private LocalDateTime syncDate;
private LocalDateTime onlineDate;
@ManyToOne(fetch = FetchType.LAZY)
private AmalgamationEntity curAmalgamation;
@ElementCollection(targetClass = Role.class, fetch = FetchType.EAGER)
@CollectionTable(name = "t_user_role", joinColumns = @JoinColumn(name = "user_id"))
@Enumerated(EnumType.STRING)
private Set<Role> roles;
和同时
private String password2
放置在字段上方,所以会发生这样的情况:@NotBlank
@Transient
password2
不为空,验证成功,但随后由于@Transient
该值password2
没有保存到数据库中(没有传递给创建SQL请求)@Transient
字段将等于password2
UserEntity
null
@NotBlank
。这看起来很奇怪,因为... 目前还不清楚为什么 Spring 会验证标记为 的字段@Transient
,但这就是它的工作原理。为了避免这种情况,我建议在控制器中使用另一个验证对象(DTO),在其中设置请求所需的所有规则,处理某些字段的需求、它们的相等性等。成功验证后,将此 DTO 映射到实体并在服务中使用它。
因为 实体类中有一个对数据库没有任何意义的字段是很奇怪的。