EJB3 QL中LEFT JOIN vs LEFT JOIN FETCH

在EJB3 QL中,left join 与left join fetch都是用来join查询,但是它们不同之处在于 left join fetch可以用来把lazy装载的关联数据load到查询的对象中去。除此之外,还有其它需要注意的地方。如下面的例子:

实体类定义:

@Entity(name="JobInfo") public class JobInfo implements Serializable { @OneToMany(cascade={CascadeType.PERSIST,CascadeType.MERGE},   fetch=FetchType.LAZY, mappedBy="jobInfo") @Cascade({ org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.DELETE_ORPHAN }) private Set<JobRunInfos> jobRunInfos = new HashSet<JobRunInfos>();

@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="CREATOR",nullable=false)
private SysUser creator;
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="EXCUTOR",nullable=false)
private SysUser excutor;

EJB3 QL语句:

"SELECT jobInfo FROM  JobInfo jobInfo
	LEFT JOIN FETCH jobInfo.creator 
	LEFT JOIN FETCH jobInfo.executor LEFT JOIN  jobInfo.jobRunInfos jobRunInfos "
   	+
" WHERE (" +
  "(jobInfo.createDate>=?1 AND jobInfo.createDate<=?2) OR " +
  "(jobRunInfos.entryDate>=?1 AND jobRunInfos.entryDate<=?2) OR " +
  "(jobRunInfos.executeDate>=?1 AND jobRunInfos.executeDate<=?2))";
  1. creator和executor因为是Lazy load的所以需要用LEFT JOIN FETCH,否则在最终查询出来的DAO对象 JobInfo中它们是不可用的。
  2. 并不是非得用了LEFT JOIN FETCH某个Lazy对象之后,在where子句中才可以使用该对象的引用。如jobRunInfos在where子句中,jobRunInfos.entryDate对其加以了引用。

又如:

"SELECT jobInfo FROM  JobInfo jobInfo
	LEFT JOIN  jobInfo.jobRunInfos jobRunInfos "
   	+
" WHERE (" +
  "(jobInfo.creator.id=?1) OR " +
  "(jobRunInfos.entryDate>=?2 AND jobRunInfos.entryDate<=?3) OR " +
  "(jobRunInfos.executeDate>=?2 AND jobRunInfos.executeDate<=?3))";
尽管它没有显示地FETCH,我们仍可在上面的where子句中引用它。如:jobInfo.creator.id=?1这句引用是正确的

3. 在where语句中,可以使用集合类来引用它个体类的属性。如 jobRunInfos.entryDate,尽管entryDate是属于JobRunInfo这个类的,但仍可以用它的集合类形式来引用它。这个没有错,除了看上去有点怪之外!

4. 如果一个集合类被LEFT JOIN FETCH,那么它的个体类一定要出现在 select 语句之后,否则就会报fetch special  exception.。如:上面的查询改成:"SELECT jobInfo FROM JobInfo jobInfo LEFT JOIN FETCH jobInfo.jobRunInfos jobRunInfos " 那么就会报错。


   

你可能感兴趣的:(DAO,JOIN,ejb,Class)