我在服务器端使用休眠框架,并以Postgres作为后端。我使用枚举类型users.user_role
(这里的用户是一个架构)。
ENUM的定义是
create type users.user_role as ENUM ('Agent', 'Customer');
现在,我正在使用“ org.postgresql.Driver”连接到数据库。为此,我正在使用postgressql-9.3-1101-jdbc4.jar。
当我尝试使用Prepared Statement插入值时,它的工作正常。正常工作的基本代码如下。
String sqlQuery = "insert into users.user (user_id, created, last_modified, client_id, email, active, data, user_role_type) values (?, ?, ?, ?, ?, ?, ?, ?)";
try {
Class.forName("org.postgresql.Driver");
Connection connection = DriverManager.getConnection("jdbc:postgresql://localhost:5432/kc_abhi","postgres","root");
PreparedStatement preparedStatement = connection.prepareStatement(sqlQuery);
preparedStatement.setObject(1, UUID.fromString("d70328f0-7301-4ce7-9c3d-64938f9c6c7d"));
preparedStatement.setObject(2, new Timestamp(System.currentTimeMillis()));
preparedStatement.setObject(3, new Timestamp(System.currentTimeMillis()));
preparedStatement.setObject(4, UUID.fromString("4753fe2b-f0a6-4ee9-8cc9-8bb20b60ef73"));
preparedStatement.setObject(5, "ab@everestek.com");
preparedStatement.setObject(6, true);
PGobject pGobject = new PGobject();
pGobject.setType("json");
pGobject.setValue("{\"data\":\"data\"}");
preparedStatement.setObject(7, pGobject);
PGobject pGobject1 = new PGobject();
pGobject1.setType("user_role");
pGobject1.setValue("Customer");
preparedStatement.setObject(8, pGobject1);
int i = preparedStatement.executeUpdate();
System.out.println("i = " + i);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
问题:
当我出于相同目的尝试使用org.hibernate.SQLQuery时,会给出ENUM错误。
错误:错误:“ user_role_type”列的类型为users.user_role,但表达式的类型为bytea
查询:
SQLQuery sqlQuery = currentSession().createSQLQuery("insert into users.user (user_id, created, last_modified, client_id, email, active, data, user_role_type, user_role_data) values (:userId, :created, :lastModified, :clientId, :email, :active, :data, :userRoleType, :userRoleData));
设置参数
PGobject pGobject1 = new PGobject();
pGobject1.setType("user_role");
pGobject1.setValue("Customer");
sqlQuery.setParameter("user_role_type", "Customer");
现在json类型发生了相同的问题。我尝试在PLSQL中为JSON发送String类型,但显示
错误:错误:“数据”列为json但表达式的类型为String
设置参数
PGobject pGobject1 = new PGobject();
pGobject1.setType("json");
pGobject1.setValue(data); //here data is of type string
sqlQuery.setParameter("data", data);
答案 0 :(得分:0)
解决方案适合我
假设我的枚举类型为ADMIN和ORGANIZATION_ADMIN。所以我的查询就是这样
create type admins.admin_role as enum ('ADMIN','ORGANIZATION_ADMIN');
create table admins.admin (
admin_id uuid not null,
name text not null,
first_name text not null,
last_name text not null,
admin_role admins.admin_role,
created timestamp not null,
last_modified timestamp not null,
created_by uuid not null references admins.admin(admin_id) deferrable initially deferred,
last_modified_by uuid not null references admins.admin(admin_id) deferrable initially deferred,
delete boolean not null default false,
primary key (admin_id),
constraint empty_name_check check ((length(name) >= 1) and (name not like 'null')),
constraint empty_first_name_check check ((length(first_name) >= 1) and (name not like 'null')),
constraint empty_last_name_check check ((length(last_name) >= 1) and (name not like 'null'))
);
因此,要使用Java枚举类型对此进行映射,我们需要添加一个类。我给了名字EnumerationType,它扩展了org.hibernate.type.EnumType并定义了nullSafeSet方法。
我的EnumerationType.java如下
package com.schoolmanager.postgres.type.enumeration;
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SessionImplementor;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Types;
public class EnumerationType extends org.hibernate.type.EnumType {
public void nullSafeSet(
PreparedStatement st,
Object value,
int index,
SessionImplementor session)
throws HibernateException, SQLException {
if (value == null) {
st.setNull(index, Types.OTHER);
} else {
st.setObject(index, value.toString(), Types.OTHER);
}
}
}
现在,当我不得不使用这种映射时,我需要添加TypeDefs。首先,我们需要在Java中创建枚举。
public enum AdminRole {
ADMIN("ADMIN"),
ORGANIZATION_ADMIN("ORGANIZATION_ADMIN");
private String value;
AdminRole(String value) {
this.value = value;
}
}
然后我们可以如下使用它。
@Entity
@Table(schema = "admins", name = "admin", uniqueConstraints = @UniqueConstraint(columnNames={"adminId"}))
@TypeDefs({
@TypeDef(name = "EnumerationType", typeClass = EnumerationType.class)
})
public class Admin {
private UUID adminId;
private String name;
private String firstName;
private String lastName;
private AdminRole adminRole;
private Date created;
private Date lastModified;
private UUID createdBy;
private UUID lastModifiedBy;
private boolean delete;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
public UUID getAdminId() {
return adminId;
}
public void setAdminId(UUID adminId) {
this.adminId = adminId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
@Basic
@Enumerated(EnumType.STRING)
@Type(type = "EnumerationType")
public AdminRole getAdminRole() {
return adminRole;
}
public void setAdminRole(AdminRole adminRole) {
this.adminRole = adminRole;
}
@Column(columnDefinition="TIMESTAMP DEFAULT CURRENT_TIMESTAMP")
@Temporal(TemporalType.TIMESTAMP)
public Date getCreated() {
return created;
}
public void setCreated(Date created) {
this.created = created;
}
@Column(columnDefinition="TIMESTAMP DEFAULT CURRENT_TIMESTAMP")
@Temporal(TemporalType.TIMESTAMP)
public Date getLastModified() {
return lastModified;
}
public void setLastModified(Date lastModified) {
this.lastModified = lastModified;
}
public UUID getCreatedBy() {
return createdBy;
}
public void setCreatedBy(UUID createdBy) {
this.createdBy = createdBy;
}
public UUID getLastModifiedBy() {
return lastModifiedBy;
}
public void setLastModifiedBy(UUID lastModifiedBy) {
this.lastModifiedBy = lastModifiedBy;
}
public boolean isDelete() {
return delete;
}
public void setDelete(boolean delete) {
this.delete = delete;
}
}
您需要添加TypeDefs,例如 @TypeDefs({ @TypeDef(name =“ EnumerationType”,typeClass = EnumerationType.class) })
然后,您需要添加注释以将类与枚举类型相关联,就像我的情况一样
@Basic
@Enumerated(EnumType.STRING)
@Type(type = "EnumerationType")
现在您可以将此数据保存在admin_role为enum_type的管理表中。