今天在改写hibernate项目时,发现一个严重的问题,假如我想加二级缓存,那么就必须使用addentity()方法来指定具体的实体类,
但是我一加具体的实体类时,查询语句就会多出多个无关联的查询语句,这个问题搞了我一下午,现在把这个问题贴出来
BaseDaoImpl.java
SQLQuery query = getSession().createSQLQuery(hql).addEntity(t.getClass());
query.setCacheable(true);
SubjectBizImpl.java
String sql="select s.id,ed.editionName,s.editionId,s.semester,s.subjectName,s.chapterCount,s.seq from subject s right join edition ed on s.editionId=ed.id";
Map param=new HashMap();
List
subject=null;
if(subjectPage!=null){
sql+=" where ";
if(subjectPage.getEditionName()!=null && !"".equals(subjectPage.getEditionName().trim())){
sql+=" ed.editionName like '%"+subjectPage.getEditionName()+"%' and ";
}
if(subjectPage.getSemester()!=null && !"".equals(subjectPage.getSemester().trim())){
sql+=" s.semester like '%"+subjectPage.getSemester().trim()+"%' and ";
}
sql+=" 1=1";
}
if(page==null || rows==null){
subject = baseDao.searchByPro(sql, null, null,param,new Subject());
}else{
//分页
int startPage=(page-1)*rows;
sql+=" limit "+startPage+","+rows;
subject= baseDao.searchByPro(sql, startPage, rows,param,new Subject());
}
addEntity(t.getClass())
方法,那么就会出现这个问题,后面我又仔细的看了一下subject这个映射类
@Entity
@Table(name = "Subject")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class Subject implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(length = 100, nullable = false)
private String subjectName;// 课程名
@Column(nullable = false)
private Integer chapterCount;// 所含章节数
@Column(length = 50, nullable = false)
private String semester;// 课程所属学期
@Column
private Integer seq;
public Integer getSeq() {
return seq;
}
public void setSeq(Integer seq) {
this.seq = seq;
}
@ManyToOne
@JoinColumn(name = "editionId", nullable = false)
private Edition edition;
@OneToMany(mappedBy = "subject")
private Set chapters = new HashSet();
@OneToMany(mappedBy = "subject")
private Set pointInfos = new HashSet();
@OneToMany(mappedBy="subject")
private Set pointPapers= new HashSet();
public Set getPointPapers() {
return pointPapers;
}
public void setPointPapers(Set pointPapers) {
this.pointPapers = pointPapers;
}
public Set getPointInfos() {
return pointInfos;
}
public void setPointInfos(Set pointInfos) {
this.pointInfos = pointInfos;
}
public Set getChapters() {
return chapters;
}
public void setChapters(Set chapters) {
this.chapters = chapters;
}
public Edition getEdition() {
return edition;
}
public void setEdition(Edition edition) {
this.edition = edition;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getSubjectName() {
return subjectName;
}
public void setSubjectName(String subjectName) {
this.subjectName = subjectName;
}
public Integer getChapterCount() {
return chapterCount;
}
public void setChapterCount(Integer chapterCount) {
this.chapterCount = chapterCount;
}
public String getSemester() {
return semester;
}
public void setSemester(String semester) {
this.semester = semester;
}
后面我通过问别人,最中解决了这个问题,在映射实体类里@ManyToOne这个注解,它有个默认的属性
FetchType fetch() default EAGER;
这个属性默认为懒加载为全部抓取,所以,那个查询语句总是会出现多个无关的语句
最后在@ManyToOne这个注解里修改一下这个属性的值
@ManyToOne(fetch=FetchType.LAZY)
将它改为延迟抓取LAZY,就这样,这个问题圆满解决了
最后再说一点,使用这个属性一定要注意一下,它有可能会让你抓不到数据的,可以自己去了解一下懒加载
还有一个问题,假如你想要使用二级缓存机制,就一定要用到addentity()方法的,不然会报错的