如何使用JPA和Hibernate映射PostgreSQL枚举
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了如何使用JPA和Hibernate映射PostgreSQL枚举,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含6095字,纯文字阅读大概需要9分钟。
内容图文
![如何使用JPA和Hibernate映射PostgreSQL枚举](/upload/InfoBanner/zyjiaocheng/888/cd35230c34c54b099a763c92c1eb2493.jpg)
我正在尝试将名为transmission_result的postgres自定义类型映射到Hibernate / JPA POJO. postgres自定义类型或多或少是枚举类型的字符串值.
我创建了一个名为PGEnumUserType的自定义EnumUserType以及一个表示postgres枚举值的枚举类.当我针对真实数据库运行此操作时,收到以下错误:
‘ERROR:column“status”的类型为transmission_result,但表达式的类型为字符变化
提示:您需要重写或转换表达式.
位置:135′
看到这个,我想我需要将我的SqlTypes更改为Types.OTHER.但这样做会破坏我的集成测试(在内存数据库中使用HyperSQL):
‘引起:java.sql.SQLException:在语句中找不到表[select enrollment0 _.“id”as id1_47_0_,enrollment0 _.“tpa_approval_id”as tpa2_47_0_,enrollment0 _.“tpa_status_code”as tpa3_47_0_,enrollment0 _.“status_message”as status4_47_0_,enrollment0_ .“approval_id”as approval5_47_0_,enrollment0 _.“transmission_date”as transmis6_47_0_,enrollment0 _.“status”as status7_47_0_,enrollment0 _.“transmit”as transmit8_47_0_ from“transmitting”enrollment0_ where enrollment0 _.“id”=?]’
我不确定为什么更改sqlType会导致此错误.任何帮助表示赞赏.
JPA / Hibernate实体:
@Entity
@Access(javax.persistence.AccessType.PROPERTY)
@Table(name="transmissions")
public class EnrollmentCycleTransmission {
// elements of enum status column
private static final String ACCEPTED_TRANSMISSION = "accepted";
private static final String REJECTED_TRANSMISSION = "rejected";
private static final String DUPLICATE_TRANSMISSION = "duplicate";
private static final String EXCEPTION_TRANSMISSION = "exception";
private static final String RETRY_TRANSMISSION = "retry";
private Long transmissionID;
private Long approvalID;
private Long transmitterID;
private TransmissionStatusType transmissionStatus;
private Date transmissionDate;
private String TPAApprovalID;
private String TPAStatusCode;
private String TPAStatusMessage;
@Column(name = "id")
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
public Long getTransmissionID() {
return transmissionID;
}
public void setTransmissionID(Long transmissionID) {
this.transmissionID = transmissionID;
}
@Column(name = "approval_id")
public Long getApprovalID() {
return approvalID;
}
public void setApprovalID(Long approvalID) {
this.approvalID = approvalID;
}
@Column(name = "transmitter")
public Long getTransmitterID() {
return transmitterID;
}
public void setTransmitterID(Long transmitterID) {
this.transmitterID = transmitterID;
}
@Column(name = "status")
@Type(type = "org.fuwt.model.PGEnumUserType" , parameters ={@org.hibernate.annotations.Parameter(name = "enumClassName",value = "org.fuwt.model.enrollment.TransmissionStatusType")} )
public TransmissionStatusType getTransmissionStatus() {
return this.transmissionStatus ;
}
public void setTransmissionStatus(TransmissionStatusType transmissionStatus) {
this.transmissionStatus = transmissionStatus;
}
@Column(name = "transmission_date")
public Date getTransmissionDate() {
return transmissionDate;
}
public void setTransmissionDate(Date transmissionDate) {
this.transmissionDate = transmissionDate;
}
@Column(name = "tpa_approval_id")
public String getTPAApprovalID() {
return TPAApprovalID;
}
public void setTPAApprovalID(String TPAApprovalID) {
this.TPAApprovalID = TPAApprovalID;
}
@Column(name = "tpa_status_code")
public String getTPAStatusCode() {
return TPAStatusCode;
}
public void setTPAStatusCode(String TPAStatusCode) {
this.TPAStatusCode = TPAStatusCode;
}
@Column(name = "status_message")
public String getTPAStatusMessage() {
return TPAStatusMessage;
}
public void setTPAStatusMessage(String TPAStatusMessage) {
this.TPAStatusMessage = TPAStatusMessage;
}
}
自定义EnumUserType:
public class PGEnumUserType implements UserType, ParameterizedType {
private Class<Enum> enumClass;
public PGEnumUserType(){
super();
}
public void setParameterValues(Properties parameters) {
String enumClassName = parameters.getProperty("enumClassName");
try {
enumClass = (Class<Enum>) Class.forName(enumClassName);
} catch (ClassNotFoundException e) {
throw new HibernateException("Enum class not found ", e);
}
}
public int[] sqlTypes() {
return new int[] {Types.VARCHAR};
}
public Class returnedClass() {
return enumClass;
}
public boolean equals(Object x, Object y) throws HibernateException {
return x==y;
}
public int hashCode(Object x) throws HibernateException {
return x.hashCode();
}
public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException {
String name = rs.getString(names[0]);
return rs.wasNull() ? null: Enum.valueOf(enumClass,name);
}
public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
if (value == null) {
st.setNull(index, Types.VARCHAR);
}
else {
st.setString(index,((Enum) value).name());
}
}
public Object deepCopy(Object value) throws HibernateException {
return value;
}
public boolean isMutable() {
return false; //To change body of implemented methods use File | Settings | File Templates.
}
public Serializable disassemble(Object value) throws HibernateException {
return (Enum) value;
}
public Object assemble(Serializable cached, Object owner) throws HibernateException {
return cached;
}
public Object replace(Object original, Object target, Object owner) throws HibernateException {
return original;
}
public Object fromXMLString(String xmlValue) {
return Enum.valueOf(enumClass, xmlValue);
}
public String objectToSQLString(Object value) {
return '\'' + ( (Enum) value ).name() + '\'';
}
public String toXMLString(Object value) {
return ( (Enum) value ).name();
}
}
枚举类:
public enum TransmissionStatusType {
accepted,
rejected,
duplicate,
exception,
retry}
解决方法:
我想到了.我需要在nullSafeSet函数中使用setObject而不是setString,并将Types.OTHER作为java.sql.type传入,让jdbc知道它是postgres类型.
public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
if (value == null) {
st.setNull(index, Types.VARCHAR);
}
else {
// previously used setString, but this causes postgresql to bark about incompatible types.
// now using setObject passing in the java type for the postgres enum object
// st.setString(index,((Enum) value).name());
st.setObject(index,((Enum) value), Types.OTHER);
}
}
内容总结
以上是互联网集市为您收集整理的如何使用JPA和Hibernate映射PostgreSQL枚举全部内容,希望文章能够帮你解决如何使用JPA和Hibernate映射PostgreSQL枚举所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。