Hibernate中的预测

时间:2013-11-18 10:54:37

标签: java hibernate

我有两个类(学生和马克)在休眠中有一对多的关系。

Mark Class

@Entity
@Table(name = "MARK")
public class Mark {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "ID")
private int id;
private int sub1;
private int sub2;
@ManyToOne
@JoinColumn(columnDefinition = "studentid", referencedColumnName = "ID")
private Student student;

public int getId() {
    return id;
}

public void setId(int id) {
    this.id = id;
}

public int getSub1() {
    return sub1;
}

public void setSub1(int sub1) {
    this.sub1 = sub1;
}

public int getSub2() {
    return sub2;
}

public void setSub2(int sub2) {
    this.sub2 = sub2;
}

public Student getStudent() {
    return student;
}

public void setStudent(Student student) {
    this.student = student;
}

@Override
public String toString() {
    return "Mark [id=" + id + ", student=" + student + ", sub1=" + sub1
            + ", sub2=" + sub2 + "]";
}

    }

学生班

   @Entity
   @Table(name = "STUDENT")
   public class Student {


@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "ID")
private int id;
private String fName;
private String lName;
@OneToMany
private List<Mark> marks;

public int getId() {
    return id;
}

public void setId(int id) {
    this.id = id;
}

public String getFName() {
    return fName;
}

public void setFName(String fName) {
    this.fName = fName;
}

public String getLName() {
    return lName;
}

public void setLName(String lName) {
    this.lName = lName;
}

public List<Mark> getMarks() {
    return marks;
}

public void setMarks(List<Mark> marks) {
    this.marks = marks;
}

@Override
public String toString() {
    return "Student [fName=" + fName + ", id=" + id + ", lName=" + lName
            + ", marks=" + marks + "]";
}

}

测试方法:

public void testMethod(){
    try{
        Criteria criteria = utilitiesDAO.getCriteria(Mark.class);
        criteria.createAlias("student", "student");
        ProjectionList projections = Projections.projectionList();
        projections.add(Projections.property("id"),"id");
        projections.add(Projections.property("sub1"),"sub1");
        projections.add(Projections.property("student"),"student");
                    projections.add(Projections.alias(Projections.property("student.fName"),"student.fName"));
        criteria.setProjection(projections);
        criteria.setResultTransformer(Transformers.aliasToBean(Mark.class));
        List ll = criteria.list();
        System.out.println(ll);
    }catch (Exception e) {
        e.printStackTrace();
    }
}

我需要的是fname表格学生带有数据库中的Mark详细信息。 由Hibernate标准生成的查询是

Hibernate: select this_.ID as y0_, this_.sub1 as y1_, student1_.fName as y2_ from MARK this_ inner join STUDENT student1_ on this_.student_ID=student1_.ID

我得到了例外:

   org.hibernate.PropertyNotFoundException: Could not find setter for student.fName on class
   at                     org.hibernate.property.ChainedPropertyAccessor.getSetter(ChainedPropertyAccessor.java:67)
   at org.hibernate.transform.AliasToBeanResultTransformer.initialize(AliasToBeanResultTransformer.java:118)
   at org.hibernate.transform.AliasToBeanResultTransformer.transformTuple(AliasToBeanResultTransformer.java:81)
   at org.hibernate.loader.criteria.CriteriaLoader.getResultColumnOrRow(CriteriaLoader.java:158)
   at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:639)
   at org.hibernate.loader.Loader.doQuery(Loader.java:829)
   at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:274)
   at org.hibernate.loader.Loader.doList(Loader.java:2542)
   at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2276)
   at org.hibernate.loader.Loader.list(Loader.java:2271)
   at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:119)
   at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1716)
   at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:347)

1 个答案:

答案 0 :(得分:0)

你做的比实际情况要困难得多,而且你也有一些错误。

首先,映射是错误的。 OneToMany应该是:

@OneToMany(mappedBy = "student")
private List<Mark> marks;

其次,您应该更好地为您的属性命名:firstNamelastName,而不是fNamelName

您的条件查询尝试为属性“student”添加投影。但是Criteria查询不支持对实体类型属性的预测。

并尝试将AliasToBeanTransformer与对象Mark的属性sudent.fName一起使用。但这也不受支持。如果你真的想要它,你应该创建一个单独的MarkDTO类,其中包含firstName字段。从查询中返回部分填充的分离实体是一个非常糟糕的主意,这将使维护程序员(包括您)感到非常困惑:您将收到Mark的实例,但在询问他们的学生姓氏时,您会得到null,你会想知道为什么。

仅检索名字而不是整个学生实体可能不会带来任何可衡量的性能提升(特别是如果您的数据集太小以至于您无法从标记表中检索所有行),但会使您的代码更多复杂,更脆弱。

只需使用以下HQL查询,该查询将在一个查询中返回附加了学生的标记:

select m from Mark m left join fetch m.student