gpt4 book ai didi

java - Hibernate 中的投影

转载 作者:太空宇宙 更新时间:2023-11-04 15:24:13 24 4
gpt4 key购买 nike

我有两个类(class)(学生和马克)在 hibernate 中具有一对多关系。

标记类别

@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 + "]";
}

}

学生类(class)

   @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 以及数据库中的标记详细信息。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)

最佳答案

你做得比应有的要困难得多,而且你也有一些错误。

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

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

其次,您确实应该更好地命名属性:firstNamelastName,而不是fNamelName .

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

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

仅检索名字而不是整个 Student 实体可能不会带来任何可测量的性能改进(特别是如果您的数据集很小,以至于您可以从标记表中检索所有行),但会使您的代码更高效复杂,也更脆弱。

只需使用以下 HQL 查询,该查询将在单个查询中返回附有学生的分数:

select m from Mark m left join fetch m.student

关于java - Hibernate 中的投影,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20045996/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com