Java 当用户名用@email注释时,Spring或Hibernate不生成id
我目前有一个完全可以工作的Spring应用程序,经过了非常彻底的测试,现在已经在生产中成功运行了一年多。最近,我想对用户名字段进行hibernate电子邮件验证。用户名字段用于登录,也是我们用户的电子邮件 当我用Java 当用户名用@email注释时,Spring或Hibernate不生成id,java,spring,hibernate,email,hibernate-validator,Java,Spring,Hibernate,Email,Hibernate Validator,我目前有一个完全可以工作的Spring应用程序,经过了非常彻底的测试,现在已经在生产中成功运行了一年多。最近,我想对用户名字段进行hibernate电子邮件验证。用户名字段用于登录,也是我们用户的电子邮件 当我用@Email注释用户名字段时,不再生成id(用@id和@Generated(strategy=GenerationType.AUTO))并保留值null。这会导致hashCode在NullPointerException上失败(但这没有问题)。因此,由于某种原因,由于向User.java
@Email
注释用户名
字段时,不再生成id(用@id
和@Generated(strategy=GenerationType.AUTO)
)并保留值null
。这会导致hashCode
在NullPointerException
上失败(但这没有问题)。因此,由于某种原因,由于向User.java
实体添加了@Email
注释,因此不再生成id
@Entity
@Table(uniqueConstraints = @UniqueConstraint(name = "username",
columnNames = "username"))
public class User implements Serializable, UserDetails {
@GeneratedValue(strategy = GenerationType.AUTO)
@Id
private Long id;
@Column(nullable = false)
@JsonView(View.NoProfile.class)
@Email
protected String username;
@Column(nullable = false)
private String passwordHash;
@JsonIgnore
@ElementCollection(targetClass = Role.class, fetch = FetchType.EAGER)
@Enumerated(EnumType.STRING)
@CollectionTable(name = "user_role")
private Set<Role> roles;
@OneToOne(targetEntity = Profile.class, cascade = CascadeType.ALL)
@JsonView(View.Public.class)
protected Profile profile;
@JsonIgnore
private boolean accountNonExpired = true;
@JsonIgnore
private boolean accountNonLocked = true;
@JsonIgnore
private boolean credentialsNonExpired = true;
@JsonIgnore
private boolean enabled = true;
public User(String username, String passwordHash) {
this.username = username;
this.passwordHash = passwordHash;
this.profile = new Profile();
this.roles = new HashSet<>();
roles.add(Role.ROLE_USER);
}
User() { // jpa only
}
public Profile getProfile() {
return profile;
}
public Long getId() {
return id;
}
public void setPasswordHash(String passwordHash) {
this.passwordHash = passwordHash;
}
@Override
public Set<? extends GrantedAuthority> getAuthorities() {
return roles;
}
@Override
@JsonIgnore
public String getPassword() {
return passwordHash;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
@Override
public boolean isAccountNonExpired() {
return accountNonExpired;
}
@Override
public boolean isAccountNonLocked() {
return accountNonLocked;
}
@Override
public boolean isCredentialsNonExpired() {
return credentialsNonExpired;
}
@Override
public boolean isEnabled() {
return enabled;
}
public void resetProfile() {
this.profile = new Profile();
}
public void addRole(Role role) {
this.roles.add(role);
}
public void setAccountNonLocked(boolean accountNonLocked) {
this.accountNonLocked = accountNonLocked;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
@JsonView(View.Public.class)
public int getReference() {
return username.hashCode();
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
User user = (User) o;
return username.equals(user.username) && id.equals(user.id);
}
@Override
public int hashCode() {
int result = username.hashCode();
result = 31 * result + id.hashCode();
return result;
}
}
@实体
@表(uniqueConstraints=@UniqueConstraint(name=“username”,
columnNames=“username”))
公共类用户实现可序列化的UserDetails{
@GeneratedValue(策略=GenerationType.AUTO)
@身份证
私人长id;
@列(nullable=false)
@JsonView(View.NoProfile.class)
@电子邮件
受保护的字符串用户名;
@列(nullable=false)
私有字符串密码哈希;
@杰索尼奥雷
@ElementCollection(targetClass=Role.class,fetch=FetchType.EAGER)
@枚举(EnumType.STRING)
@CollectionTable(name=“用户角色”)
私人设定角色;
@OneTONE(targetEntity=Profile.class,cascade=CascadeType.ALL)
@JsonView(View.Public.class)
保护轮廓;
@杰索尼奥雷
私有布尔值accountNonExpired=true;
@杰索尼奥雷
私有布尔值accountNonLocked=true;
@杰索尼奥雷
private boolean CredentialsNoneExpired=true;
@杰索尼奥雷
私有布尔启用=真;
公共用户(字符串用户名、字符串密码哈希){
this.username=用户名;
this.passwordHash=passwordHash;
this.profile=新的profile();
this.roles=new HashSet();
roles.add(Role.Role\u用户);
}
User(){//仅限jpa
}
公共配置文件getProfile(){
回报曲线;
}
公共长getId(){
返回id;
}
public void setPasswordHash(字符串passwordHash){
this.passwordHash=passwordHash;
}
@凌驾
public Set问题可能是,当尝试保存用户时,hibernate会检查其是否有效。如果用户名电子邮件格式有问题,hibernate不会尝试保存它,因此id不会生成id
但是验证错误会发生什么呢?我认为它可能被你在hashCode方法中提到的NPE掩盖了。
尝试重新编写哈希代码,注意可能出现的NPE,并检查是否存在违反hibernate约束的情况。问题可能是,当尝试保存用户时,hibernate会检查其是否有效。如果用户名电子邮件格式有问题,hibernate不会尝试保存,因此id不会生成id
但是验证错误会发生什么呢?我认为它可能被你在hashCode方法中提到的NPE掩盖了。
尝试重写哈希代码,注意可能出现的NPE,并检查是否存在hibernate约束冲突。您最近没有更改数据库架构/实体,是吗?然后更新失败?是否有?更新,或者创建也很好。这发生在create
和create drop
上,因此数据库应该是正确的t、 为什么在类级别上只有一个字段的UniqueConstraint?你不应该把它写在电子邮件上吗?否则会很混乱,看这是一个样式选择,我们希望在文件顶部有唯一的约束,以便立即清除唯一的字段。而且,很遗憾,这并不能解决当前的问题。谢谢不过,为了帮助您。您最近没有更改数据库架构/实体,是吗?然后更新失败?您有吗?更新或创建也很好。这发生在create
和create drop
上,所以数据库应该是正确的。为什么在类级别只有一个字段的UniqueConstraint?不应该吗“你不能把它写在电子邮件上,否则会让人困惑,这是一个样式选择,我们希望在文件顶部有唯一的约束,以便立即清除唯一的字段。而且,不幸的是,这并不能解决手头的问题。谢谢你的帮助。所以我重写了哈希代码,以便能够处理NPE。它现在可以工作了,但这不是我最初想要的解决方案。因此,从我可以得出的结论是,@email
注释导致hashcode生成较早,id生成较晚。因为没有@email
注释,就不需要空检查(id在hashcode之前生成)。因此,我重写了hashcode以处理NPE。它现在可以工作,但不是我最初想要的解决方案。因此,从我可以得出的结论是,@email
注释导致hashcode生成较早,id生成较晚。因为没有@email
注释,空检查是nev需要er(id是在哈希代码之前生成的)。