【问题标题】:org.hibernate.PropertyNotFoundException: Could not find setter for 0org.hibernate.PropertyNotFoundException:找不到 0 的设置器
【发布时间】:2013-09-15 16:10:19
【问题描述】:

我使用 HQL 从表中仅获取选定的属性,维护非实体类对象的列表。 例如。我的实体类:

@Entity
@Table(name="STUDENT")
public class Student {
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long id;

    @Column(name="NAME", columnDefinition="TEXT", length="60", nullable = false)
    private String name;

    @ManyToOne
    @JoinColumn(name = "Dept_id", nullable = false)
    private Department department;

    // Other fields...
    // Getter-Setters
}

并且非持久性 DTO 类只有更少的类成员(例如,仅名称):

public class StudentDTO {
    private String name;
    // Getter-Setter for name
}

现在使用

public List<StudentDTO> getStudents(Long deptId) {
    List<StudentDTO> students;

    Query query = session.createQuery("select student.name " +
            "from Student as student " +
            "where Dept_id =?").setResultTransformer(new AliasToBeanResultTransformer(StudentDTO.class));
    query.setString(0, Long.toString(deptId));

    students = CommonUtil.castList(StudentDTO.class, query.list()); 
    return students;
}

castList 将任何集合转换为 ArrayList。

public static <T> List<T> castList(Class<? extends T> clazz, Collection<?> c) {
            List<T> resultList = new ArrayList<T>(c.size());
            for(Object o: c)
              resultList.add(clazz.cast(o));
            return resultList;
        }

抛出 org.hibernate.PropertyNotFoundException:在类 ../StudentDTO 上找不到 0 的设置器

参考Hibernate exception PropertyNotFoundException when using Transformer,我将查询更改为"select student.id as id,...",在StudentDTO 中包含Long id,但抛出相同的异常,说找不到1 的setter。

为每个属性提供了Getter/Setter。请提出更改建议!

【问题讨论】:

  • 明显的问题是缺少别名。尝试“选择 student.name 作为名称”
  • 另外,你能发布完整的堆栈吗?

标签: java hibernate hql


【解决方案1】:

当您使用AliasToBeanResultTransformer 时,您必须在query 中声明正确的alias 名称。类名本身表示它将使用alias 名称将结果转换为您的resultClass

AliasToBeanResultTransformer 类的transformTuple 方法使用alias 名称来查找resultClass (StudentDto) 的setter 方法:

for (int i = 0; i < aliases.length; i++) {
                    String alias = aliases[i];
                    if(alias != null) {
                        setters[i] = propertyAccessor.getSetter(resultClass, alias);
                    }
                }

为了使AliasToBeanResultTransformer 正常工作,您需要在query 中使用正确的别名。如果StudentDto 类中的属性名称是name,则应使用select student.name as name。使用select student.name as n 将再次抛出异常。您在 query 中使用的 alias 名称应与 DTO 类中的属性名称相同。

【讨论】:

    【解决方案2】:

    只需将每个列名写如下: 选择 column_name 作为 property_name , ...., from Class_name

    eg: select student.name as name from Student

    【讨论】:

      【解决方案3】:

      为 select 子句中的每个字段设置别名,这些字段与您在查询中设置为转换器类的持久性类中的字段名称相同,例如:

       public mypersistenceclass()
          {
          // define constructor
          public mypersistenceclass(){}
      
             private String username;
          // define setter and getter
      
       }
      
        public userclass()
        {
        ...
           Query query = session.createQuery("select Users.username as username ...")
            .setResultTransformer(new AliasToBeanResultTransformer(mypersistenceclass.class));
      
        ...
        }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-11-28
        • 1970-01-01
        • 2018-07-25
        • 2013-05-31
        • 2016-06-03
        相关资源
        最近更新 更多