用enum列上的where子句查询会引发异常。
org.hibernate.exception.SQLGrammarException: could not extract ResultSet
...
Caused by: org.postgresql.util.PSQLException: ERROR: operator does not exist: movedirection = bytea
Hint: No operator matches the given name and argument type(s). You might need to add explicit type casts.
SQL:
create type movedirection as enum (
'FORWARD', 'LEFT'
);
CREATE TABLE move
(
id serial NOT NULL PRIMARY KEY,
directiontomove movedirection NOT NULL
);
Hibernate映射类:
@Entity
@Table(name = "move")
public class Move {
public enum Direction {
FORWARD, LEFT;
}
@Id
@Column(name = "id")
@GeneratedValue(generator = "sequenceGenerator", strategy=GenerationType.SEQUENCE)
@SequenceGenerator(name = "sequenceGenerator", sequenceName = "move_id_seq")
private long id;
@Column(name = "directiontomove", nullable = false)
@Enumerated(EnumType.STRING)
private Direction directionToMove;
...
// getters and setters
}
调用查询的Java:
public List<Move> getMoves(Direction directionToMove) {
return (List<Direction>) sessionFactory.getCurrentSession()
.getNamedQuery("getAllMoves")
.setParameter("directionToMove", directionToMove)
.list();
}
Hibernate xml查询:
<query name="getAllMoves">
<![CDATA[
select move from Move move
where directiontomove = :directionToMove
]]>
</query>
id
而不是枚举按预期工作。没有数据库交互的Java可以正常工作:
public List<Move> getMoves(Direction directionToMove) {
List<Move> moves = new ArrayList<>();
Move move1 = new Move();
move1.setDirection(directionToMove);
moves.add(move1);
return moves;
}
createQuery
与使用@Enumerated文档通过Apache的JPA和Enums中的findByRating
示例类似,而不是使用XML查询。
select * from move where direction = 'LEFT';
预期的方式在psql中进行查询。where direction = 'FORWARD'
在XML中的查询中进行硬编码即可。.setParameter("direction", direction.name())
与.setString()
和相同,不同之处.setText()
在于:Caused by: org.postgresql.util.PSQLException: ERROR: operator does not exist: movedirection = character varying
UserType
此接受的答案https://stackoverflow.com/a/1594020/1090474建议的自定义,以及:
@Column(name = "direction", nullable = false)
@Enumerated(EnumType.STRING) // tried with and without this line
@Type(type = “full.path.to.HibernateMoveDirectionUserType”)
private Direction directionToMove;
根据与上述相同的问题,EnumType
由评分较高但未被接受的答案https://stackoverflow.com/a/1604286/1090474建议使用Hibernate进行映射,以及:
@Type(type = "org.hibernate.type.EnumType",
parameters = {
@Parameter(name = "enumClass", value = "full.path.to.Move$Direction"),
@Parameter(name = "type", value = "12"),
@Parameter(name = "useNamed", value = "true")
})
在看到https://stackoverflow.com/a/13241410/1090474之后,使用和不使用两个第二个参数
EnumType.ORDINAL
因为我想坚持使用EnumType.STRING
,它不那么脆,而且更灵活。JPA 2.1类型转换器不是必需的,但无论如何都不是选择,因为我现在使用的是JPA 2.0。
正确别名并使用 合格的属性名称 是解决方案的第一部分。
<query name="getAllMoves">
<![CDATA[
from Move as move
where move.directionToMove = :direction
]]>
</query>
@Enumerated(EnumType.STRING)
仍然无法正常工作,因此需要自定义UserType
。关键是要正确覆盖nullSafeSet
此答案中的网络实现。
@Override
public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session) throws HibernateException, SQLException {
if (value == null) {
st.setNull(index, Types.VARCHAR);
}
else {
st.setObject(index, ((Enum) value).name(), Types.OTHER);
}
}
implements ParameterizedType
没有合作:
org.hibernate.MappingException: type is not parameterized: full.path.to.PGEnumUserType
所以我不能这样注释enum属性:
@Type(type = "full.path.to.PGEnumUserType",
parameters = {
@Parameter(name = "enumClass", value = "full.path.to.Move$Direction")
}
)
相反,我这样声明了该类:
public class PGEnumUserType<E extends Enum<E>> implements UserType
使用构造函数:
public PGEnumUserType(Class<E> enumClass) {
this.enumClass = enumClass;
}
不幸的是,这意味着任何其他类似映射的枚举属性都需要这样的类:
public class HibernateDirectionUserType extends PGEnumUserType<Direction> {
public HibernateDirectionUserType() {
super(Direction.class);
}
}
注释属性,您就完成了。
@Column(name = "directiontomove", nullable = false)
@Type(type = "full.path.to.HibernateDirectionUserType")
private Direction directionToMove;
EnhancedUserType
以及它想要实现的三种方法 public String objectToSQLString(Object value)
public String toXMLString(Object value)
public String html" target="_blank">objectToSQLString(Object value)
没什么区别,所以我坚持了implements UserType
。
nullSafeGet
两个链接的解决方案的方式来使其特定于Postgres 。text
,并且原始代码可以正常运行而无需额外的工作。Spring 3.x、JPA 2.0、Hibernate 4.x、Postgresql 9.x. 使用希望映射到Postgresql枚举的枚举属性处理Hibernate映射类。 使用枚举列上的where子句进行查询会引发异常。 SQL: Hibernate xml查询: > 按而不是按枚举查询工作正常。 没有数据库交互的Java工作良好: 不是,与和相同,异常更改为: 在查看https://sta
问题内容: 我需要预先将没有实现接口的枚举映射到现有数据库,该数据库使用将该枚举存储在与所有者类相同的表中。 在这种情况下应如何处理映射?持久化到数据库不会改变,因为实现该接口的所有枚举都将具有不同的值,但是我不确定应如何从数据库中检索对象(我是否需要自定义映射器,它将尝试实例化一个使用指定的enum类进行枚举吗?Hibernate是否本身支持此功能?)。 问题答案: 可以创建一个自定义(例如th
问题内容: Hibernate提供的注释支持使用或两种类型的映射。当我们使用映射时,它使用的“名称” 而不是Enum 的表示形式。在数据库列仅包含一个字符的情况下,这是一个问题。例如,我有以下枚举: 当我坚持枚举使用,即休眠尝试在数据库中存储的值是开放的。但是,我的数据库列仅包含一个字符,因此会引发异常。 克服这个问题的一个办法是改变枚举类型持有单个字符(如,代替,)。但是,这降低了可读性。有什么
问题内容: 在我的MySQL数据库中,有“ gender enum(’male’,’female’)”列 我创建了枚举“ com.mydomain.myapp.enums.Gender”,并在我的实体中定义了“性别”。 现在,我想将枚举类型保留在我的MySQL数据库中,但是当我启动应用程序时,我得到: 性别列在MyApp.Person中的列类型错误。找到:枚举,预期:整数 为什么是这样?就像我用“
问题内容: Enumeration <有区别吗?扩展ZipEntry>和Enumeration ?如果是这样,有什么区别? 问题答案: 拥有其中一种后,您在做什么上没有实际差异,因为type参数仅在“输出”位置使用。另一方面,在您可以 用作 其中一个的方面有很大的不同。 假设您有一个-您无法将其传递给作为其参数之一的方法。您 可以 将其传递给采用方法。 当您有一个在输入和输出位置都使用type参数
问题内容: 枚举具有获取枚举常量的方法,并且在具有 我发现的名称的类中存在的相同类型的方法都给出相同的输出。那还有什么其他区别。如果没有区别,那么为什么要添加JSL ? 问题答案: 包括该方法的原因是它可以与任何方法一起使用。相比之下, 用于特定方法的方法仅适用于该特定方法…,因为类不能被多态使用。 显然,该方法仅在您实现 需要 针对多种类型使用的代码的情况下才真正有用……而泛型则不会削减它。