5

我使用 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 的设置器

在使用 Transformer 时引用Hibernate 异常 PropertyNotFoundException ,我将查询更改为"select student.id as id,...",在Long id内部StudentDTO但抛出相同的异常,说 setter not found for 1。

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

4

3 回答 3

20

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

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

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 类中的属性名称相同。

于 2013-09-12T03:24:11.963 回答
5

只需按如下方式编写每个列名:从 Class_name 中选择 column_name 作为 property_name ,....

例如:从 Student中选择 student.name作为名称

于 2016-06-23T06:08:08.573 回答
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));

  ...
  }
于 2015-07-23T06:27:52.323 回答