org.hibernate.PropertyNotFoundException:无法找到0的setter

时间:2013-09-11 14:51:04

标签: java hibernate hql

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

@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:在类上找不到0的setter ../ StudentDTO

参考Hibernate exception PropertyNotFoundException when using Transformer,我将查询更改为"select student.id as id,..."Long idStudentDTO,但发出同样的异常,说找不到1的setter。

每个酒店都会获得Getter / Setter。请建议更改!

3 个答案:

答案 0 :(得分:17)

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

transformTuple类的AliasToBeanResultTransformer方法使用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将再次抛出异常。您在alias中使用的query名称应与DTO类中的属性名称相同。

答案 1 :(得分:4)

为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));

  ...
  }

答案 2 :(得分:3)

只需编写每个列名称,如下所示: 从class_name

中选择column_name作为property_name,....
  

例如:从学生

中选择student.name 作为名称