我正在尝试将Postgres自定义类型(名为transmission_result)映射到Hibernate / JPA
POJO。postgres自定义类型或多或少是字符串值的枚举类型。
我创建了一个名为PGEnumUserType的自定义EnumUserType以及一个表示postgres枚举值的枚举类。当我对一个真实的数据库运行它时,我收到以下错误:’ERROR:列“状态”的类型为transmission_result,但表达式的类型字符不同提示:您将需要重写或强制转换表达式。位置:135’
看到此消息后,我发现需要将SqlTypes更改为Types.OTHER。但这会破坏我的集成测试(在内存DB中使用HyperSQL),并显示以下消息:’引起原因:java.sql.SQLException:在语句[select
enrollment0 。“ id”作为id1_47_0,enrollment0 。“
tpa_approval_id”作为tpa2_47_0_中找不到表,将注册0 。“ tpa_status_code”设置为tpa3_47_0_,将注册0
。“ status_message”作为状态4_47_0,将注册0 。“
approval_id”作为批准5_47_0,将注册0_。“发送日期”作为transmis6_47_0_作为状态4“将发送,将注册0_从”
0“发送给注册4_。传输” enrollment0_,其中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);
}
}
Spring 3.x、JPA 2.0、Hibernate 4.x、Postgresql 9.x. 使用希望映射到Postgresql枚举的枚举属性处理Hibernate映射类。 使用枚举列上的where子句进行查询会引发异常。 SQL: Hibernate xml查询: > 按而不是按枚举查询工作正常。 没有数据库交互的Java工作良好: 不是,与和相同,异常更改为: 在查看https://sta
问题内容: 在此代码中,如何为组合键生成Java类(如何在休眠状态下组合键): 问题答案: 要映射组合键,你可以使用 或在注解。我知道这个问题不仅仅涉及,但规范定义的规则也适用。因此,它们是: 2.1.4主键和实体身份 … 组合主键必须对应于单个持久性字段或属性,或者对应于如下所述的一组此类字段或属性。必须定义一个主键类来表示一个复合主键。当数据库密钥由几列组成时,从传统数据库进行映射时,通常会出
问题内容: 我需要预先将未实现接口的枚举映射到现有数据库,该数据库使用将该枚举存储在与所有者类相同的表中。 在这种情况下应如何处理映射?持久化到数据库不会改变,因为实现该接口的所有枚举都将具有不同的值,但是我不确定应如何从数据库中检索对象(我是否需要自定义映射器,它将尝试实例化一个使用指定的enum类进行枚举吗?Hibernate本身是否支持此功能?)。 问题答案: 可以创建一个自定义(例如thi
问题内容: Hibernate提供的注释支持使用或的两种类型的映射。当我们使用映射时,它使用的“名称” 而不是Enum的表示形式。在数据库列仅包含一个字符的情况下,这是一个问题。例如,我有以下枚举: 当我坚持枚举使用,即hibernate尝试在数据库中存储的值是开放的。但是,我的数据库列仅包含一个字符,因此会引发异常。 克服这个问题的一个办法是改变枚举类型持有单个字符(如,代替,)。但是,这降低了
问题内容: 我的Java Bean具有childCount属性。此属性 未映射到数据库列 。取而代之的是,它应该 由数据库通过对Java bean及其子级的联接进行操作 的 函数 来 计算 。如果可以按需/“延迟”计算此属性,那就更好了,但这不是强制性的。 在最坏的情况下,我可以使用HQL或Criteria API设置此bean的属性,但我不希望这样做。 Hibernate 批注可能会有所帮助,但
我似乎在使用以下JPA代码段将PostgreSQL货币类型映射到java.util.Currency类型时遇到问题: 列cafl\u预算金额是PostgreSQL中的货币类型。 当代码以7.1.1的形式部署到JBoss中时,我得到了本文末尾显示的跟踪。有人处理过那张地图吗?