我在映射中遇到异常:
@Enumerated(value=EnumType.STRING)
public AuthenticationVendor getProvider() {
return this.provider;
}
这是枚举
public enum AuthenticationVendor {
LOCALDB, GOOGLE, FACEBOOK
}
异常似乎表明hibernate正在使用org.hibernate.type.EnumType$OrdinalEnumValueMapper
来获取基于堆栈跟踪的值:
Caused by: org.postgresql.util.PSQLException: Bad value for type int : LOCALDB
at org.postgresql.jdbc.PgResultSet.toInt(PgResultSet.java:2831)
at org.postgresql.jdbc.PgResultSet.getInt(PgResultSet.java:2088)
at org.postgresql.jdbc.PgResultSet.getInt(PgResultSet.java:2502)
at com.zaxxer.hikari.pool.HikariProxyResultSet.getInt(HikariProxyResultSet.java)
at org.hibernate.type.EnumType$OrdinalEnumValueMapper.getValue(EnumType.java:337)
这只是Postgres的一个问题 - 当我用H2数据库进行单元测试时,它运行正常。这是Postgres的表(注意我的@Id
确实是一个字符串并且工作正常):
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
------------------+-----------------------------+-----------+----------+---------+----------+--------------+-------------
id | character varying(255) | | not null | | extended | |
created | timestamp without time zone | | | | plain | |
active | boolean | | not null | | plain | |
password | character varying(255) | | not null | | extended | |
provider | character varying(255) | | | | extended | |
salt | bytea | | | | extended | |
useremailaddress | character varying(255) | | | | extended | |
userphonenumber | character varying(255) | | | | extended | |
username | character varying(255) | | not null | | extended | |
这是整个实体:
@Entity
@Table(name = "app_user",
uniqueConstraints = {
@UniqueConstraint(columnNames = {"username"})
}
)
@NamedQueries(
@NamedQuery(name = "AppUser.findByUsername", query = "SELECT U FROM AppUser U WHERE U.username = :username")
)
public final class AppUser extends BaseEntity {
static final SecureRandom sr = new SecureRandom();
String username;
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
String password;
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
byte[] salt;
AuthenticationVendor provider;
String userPhoneNumber;
String userEmailAddress;
boolean active;
public AppUser() {
super();
provider = AuthenticationVendor.LOCALDB;
}
public static byte[] randomSalt() {
return new BigInteger(130, sr).toString(32).getBytes();
}
public static String hashPassword(byte[] salt, String password)
throws NoSuchAlgorithmException, InvalidKeySpecException {
KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 65536, 128);
SecretKeyFactory f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
byte[] hash = f.generateSecret(spec).getEncoded();
Base64.Encoder enc = Base64.getEncoder();
return enc.encodeToString(hash);
}
public boolean validatePassword(String maybePassword)
throws Exception {
try {
String pw = hashPassword(this.salt, maybePassword);
return pw.equals(this.getPassword());
} catch (Exception e) {
throw new Exception(e);
}
}
public void changePassword(String newPassword)
throws Exception {
try {
this.salt = randomSalt();
this.setPassword(hashPassword(this.salt, newPassword));
} catch (Exception e) {
throw new Exception(e);
}
}
@NotNull
public String getUsername() {
return this.username;
}
@NotNull
public String getPassword() {
return this.password;
}
public byte[] getSalt() {
return this.salt;
}
@Enumerated(value=EnumType.STRING)
public AuthenticationVendor getProvider() {
return this.provider;
}
public String getUserPhoneNumber() {
return this.userPhoneNumber;
}
public String getUserEmailAddress() {
return this.userEmailAddress;
}
public boolean isActive() {
return this.active;
}
public void setUsername(String username) {
this.username = username;
}
public void setPassword(String password) {
this.password = password;
}
public void setSalt(byte[] salt) {
this.salt = salt;
}
public void setProvider(AuthenticationVendor provider) {
this.provider = provider;
}
public void setUserPhoneNumber(String userPhoneNumber) {
this.userPhoneNumber = userPhoneNumber;
}
public void setUserEmailAddress(String userEmailAddress) {
this.userEmailAddress = userEmailAddress;
}
public void setActive(boolean active) {
this.active = active;
}
public boolean equals(Object o) {
if (o == this)
return true;
if (!(o instanceof AppUser))
return false;
final AppUser other = (AppUser) o;
if (!other.canEqual((Object) this))
return false;
final Object this$username = this.getUsername();
final Object other$username = other.getUsername();
if (this$username == null ? other$username != null : !this$username.equals(other$username))
return false;
final Object this$password = this.getPassword();
final Object other$password = other.getPassword();
if (this$password == null ? other$password != null : !this$password.equals(other$password))
return false;
if (!Arrays.equals(this.getSalt(), other.getSalt()))
return false;
final Object this$provider = this.getProvider();
final Object other$provider = other.getProvider();
if (this$provider == null ? other$provider != null : !this$provider.equals(other$provider))
return false;
final Object this$userPhoneNumber = this.getUserPhoneNumber();
final Object other$userPhoneNumber = other.getUserPhoneNumber();
if (this$userPhoneNumber == null ?
other$userPhoneNumber != null :
!this$userPhoneNumber.equals(other$userPhoneNumber))
return false;
final Object this$userEmailAddress = this.getUserEmailAddress();
final Object other$userEmailAddress = other.getUserEmailAddress();
if (this$userEmailAddress == null ?
other$userEmailAddress != null :
!this$userEmailAddress.equals(other$userEmailAddress))
return false;
if (this.isActive() != other.isActive())
return false;
return true;
}
public int hashCode() {
final int PRIME = 59;
int result = 1;
final Object $username = this.getUsername();
result = result * PRIME + ($username == null ? 43 : $username.hashCode());
final Object $password = this.getPassword();
result = result * PRIME + ($password == null ? 43 : $password.hashCode());
result = result * PRIME + Arrays.hashCode(this.getSalt());
final Object $provider = this.getProvider();
result = result * PRIME + ($provider == null ? 43 : $provider.hashCode());
final Object $userPhoneNumber = this.getUserPhoneNumber();
result = result * PRIME + ($userPhoneNumber == null ? 43 : $userPhoneNumber.hashCode());
final Object $userEmailAddress = this.getUserEmailAddress();
result = result * PRIME + ($userEmailAddress == null ? 43 : $userEmailAddress.hashCode());
result = result * PRIME + (this.isActive() ? 79 : 97);
return result;
}
protected boolean canEqual(Object other) {
return other instanceof AppUser;
}
public String toString() {
return "AppUser(username=" + this.getUsername() + ", provider=" + this.getProvider() +
", userPhoneNumber=" + this.getUserPhoneNumber() + ", userEmailAddress=" +
this.getUserEmailAddress() + ", active=" + this.isActive() + ")";
}
}
答案 0 :(得分:1)
你需要在 Postgresql 中定义一个枚举类型:
create type authentication_vendor as enum ('LOCALDB', 'GOOGLE', 'FACEBOOK');
并在您的表中定义 provider
到 authentication_vendor
类型:
Column | Type | Collation | Nullable |
id | character varying(255) | | not null |
created | timestamp without time zone | | |
active | boolean | | not null |
password | character varying(255) | | not null |
provider | authentication_vendor | | |
salt | bytea | | |
useremailaddress | character varying(255) | | |
userphonenumber | character varying(255) | | |
username | character varying(255) | | not null |
在您的实体中,您需要在类级别和列级别定义类型:
@Entity
@Table(name = "app_user",
uniqueConstraints = {
@UniqueConstraint(columnNames = {"username"})
}
)
@NamedQueries(
@NamedQuery(name = "AppUser.findByUsername", query = "SELECT U FROM AppUser U WHERE U.username = :username")
)
@TypeDef(name = "pgsql_enum", typeClass = PostgreSQLEnumType.class)
public final class AppUser extends BaseEntity {
static final SecureRandom sr = new SecureRandom();
String username;
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
String password;
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
byte[] salt;
@Enumerated(EnumType.STRING)
@Type(type = "pgsql_enum")
AuthenticationVendor provider;
String userPhoneNumber;
String userEmailAddress;
boolean active;
// constructors
// getters and setters
}