org.hibernate.QueryException-- 无法解析属性

Posted

技术标签:

【中文标题】org.hibernate.QueryException-- 无法解析属性【英文标题】:org.hibernate.QueryException-- could not resolve property 【发布时间】:2017-09-12 07:48:04 【问题描述】:

我有一个像下面这样的实体:

@Entity
public class Country implements Serializable 
    private static final long serialVersionUID = 1L;
    @Id
    private Long id;
    @Type(type="secureString") //This is my custom user type and it is working fine in the sense I am able to insert, select and update records using it.
    private SecureString            nationality;
    // getters and setters

SecureString 类如下:

public class SecureString implements Serializable 


    private static final long serialVersionUID = 1L;
    private String actualValue;

    private String formattedValue;
    //getters and setters

The column name in db for this attibute is named "nationality"

国籍只有一栏。为此,我正在使用 Hibernate Custom UserType。早些时候,此属性的类型为 String,而不是 SecureString

我收到了异常 java.lang.IllegalArgumentException: org.hibernate.QueryException: could not resolve property: actualValue of: mypackge.Country.

形成的 HQL 是:

select s FROM mypackage.Country s  
WHERE  LOWER(s.nationality.actualValue) LIKE LOWER(:nationality_actualValue);

根据日志,我们可以看到 Hibernate 正在尝试在 Country 类中查找名称为 actualValue 的属性,同时将 HQl 转换为 SQl。我该如何解决这个问题?

注意:我还希望我可以在同一个实体类中使用多个 SecureString 类型的属性。

日志:

at org.hibernate.QueryException.generateQueryException(QueryException.java:120) ~[hibernate-core-5.2.8.Final.jar:5.2.8.Final]
    at org.hibernate.QueryException.wrapWithQueryString(QueryException.java:103) ~[hibernate-core-5.2.8.Final.jar:5.2.8.Final]
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:217) ~[hibernate-core-5.2.8.Final.jar:5.2.8.Final]
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:141) ~[hibernate-core-5.2.8.Final.jar:5.2.8.Final]
    at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:115) ~[hibernate-core-5.2.8.Final.jar:5.2.8.Final]
    at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:77) ~[hibernate-core-5.2.8.Final.jar:5.2.8.Final]
    at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:153) ~[hibernate-core-5.2.8.Final.jar:5.2.8.Final]
    at org.hibernate.internal.AbstractSharedSessionContract.getQueryPlan(AbstractSharedSessionContract.java:545) ~[hibernate-core-5.2.8.Final.jar:5.2.8.Final]
    at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:654) ~[hibernate-core-5.2.8.Final.jar:5.2.8.Final]
    ... 142 common frames omitted
Caused by: org.hibernate.QueryException: could not resolve property: actualValue of: mypackage.Country
    at org.hibernate.persister.entity.AbstractPropertyMapping.propertyException(AbstractPropertyMapping.java:62) ~[hibernate-core-5.2.8.Final.jar:5.2.8.Final]
    at org.hibernate.persister.entity.AbstractPropertyMapping.toType(AbstractPropertyMapping.java:56) ~[hibernate-core-5.2.8.Final.jar:5.2.8.Final]
    at org.hibernate.persister.entity.AbstractEntityPersister.toType(AbstractEntityPersister.java:1859) ~[hibernate-core-5.2.8.Final.jar:5.2.8.Final]
    at org.hibernate.hql.internal.ast.tree.FromElementType.getPropertyType(FromElementType.java:393) ~[hibernate-core-5.2.8.Final.jar:5.2.8.Final]
    at org.hibernate.hql.internal.ast.tree.FromElement.getPropertyType(FromElement.java:512) ~[hibernate-core-5.2.8.Final.jar:5.2.8.Final]
    at org.hibernate.hql.internal.ast.tree.DotNode.getDataType(DotNode.java:660) ~[hibernate-core-5.2.8.Final.jar:5.2.8.Final]
    at org.hibernate.hql.internal.ast.tree.DotNode.prepareLhs(DotNode.java:264) ~[hibernate-core-5.2.8.Final.jar:5.2.8.Final]
    at org.hibernate.hql.internal.ast.tree.DotNode.resolveInFunctionCall(DotNode.java:178) ~[hibernate-core-5.2.8.Final.jar:5.2.8.Final]
    at org.hibernate.hql.internal.ast.HqlSqlWalker.resolve(HqlSqlWalker.java:1030) ~[hibernate-core-5.2.8.Final.jar:5.2.8.Final]
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.expr(HqlSqlBaseWalker.java:1286) ~[hibernate-core-5.2.8.Final.jar:5.2.8.Final]
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.exprOrSubquery(HqlSqlBaseWalker.java:4699) ~[hibernate-core-5.2.8.Final.jar:5.2.8.Final]
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.functionCall(HqlSqlBaseWalker.java:2729) ~[hibernate-core-5.2.8.Final.jar:5.2.8.Final]
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.expr(HqlSqlBaseWalker.java:1361) ~[hibernate-core-5.2.8.Final.jar:5.2.8.Final]
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.exprOrSubquery(HqlSqlBaseWalker.java:4699) ~[hibernate-core-5.2.8.Final.jar:5.2.8.Final]
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.comparisonExpr(HqlSqlBaseWalker.java:4313) ~[hibernate-core-5.2.8.Final.jar:5.2.8.Final]
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.logicalExpr(HqlSqlBaseWalker.java:2134) ~[hibernate-core-5.2.8.Final.jar:5.2.8.Final]
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.logicalExpr(HqlSqlBaseWalker.java:2087) ~[hibernate-core-5.2.8.Final.jar:5.2.8.Final]
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.logicalExpr(HqlSqlBaseWalker.java:2084) ~[hibernate-core-5.2.8.Final.jar:5.2.8.Final]
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.logicalExpr(HqlSqlBaseWalker.java:2084) ~[hibernate-core-5.2.8.Final.jar:5.2.8.Final]
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.logicalExpr(HqlSqlBaseWalker.java:2084) ~[hibernate-core-5.2.8.Final.jar:5.2.8.Final]
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.logicalExpr(HqlSqlBaseWalker.java:2084) ~[hibernate-core-5.2.8.Final.jar:5.2.8.Final]
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.logicalExpr(HqlSqlBaseWalker.java:2062) ~[hibernate-core-5.2.8.Final.jar:5.2.8.Final]
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.whereClause(HqlSqlBaseWalker.java:813) ~[hibernate-core-5.2.8.Final.jar:5.2.8.Final]
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:607) ~[hibernate-core-5.2.8.Final.jar:5.2.8.Final]
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:311) ~[hibernate-core-5.2.8.Final.jar:5.2.8.Final]
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:259) ~[hibernate-core-5.2.8.Final.jar:5.2.8.Final]
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:261) ~[hibernate-core-5.2.8.Final.jar:5.2.8.Final]
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:189) ~[hibernate-core-5.2.8.Final.jar:5.2.8.Final]
    ... 148 common frames omitted

【问题讨论】:

你能把日志贴出来吗? 您的SecureString 未映射!? @UsagiMiyamoto 不明白这一点。我创建了一个自定义用户类型并用它注释了这个字段。你在说什么其他映射? SecureString 不是实体。 @Aldeguer:添加了日志 @UsagiMiyamoto 知道如何解决吗?我还是卡住了 【参考方案1】:

尝试创建一个转换器,如下所示:

@Converter
public class SecureConverter implements AttributeConverter<SecureString, String>

   @Override
   public String convertToDatabaseColumn(SecureString ss) 
      return ss.getActualValue();
   
   @Override
   public SecureString convertToEntityAttribute(String s)
   
      SecureString result = new SecureString();
      result.setActualValue(s);
      return result;
   

并在你的属性上使用它:

@Entity
public class Country implements Serializable

    private static final long serialVersionUID = 1L;

    @Id
    private Long id;
    @Converter(converter = Secureconverter.class)
    private SecureString nationality;

    // getters and setters

【讨论】:

我们可以同时使用 Converter 和 Custom UserType 吗?另外,我是否需要在某个地方注册这个转换器,就像我在 package-info.java 中声明 UserTypes 一样?

以上是关于org.hibernate.QueryException-- 无法解析属性的主要内容,如果未能解决你的问题,请参考以下文章