首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

Hibernate字段查询有关问题小记

2012-10-07 
Hibernate字段查询问题小记我有一个实体类,包含了BLOB字段和集合属性字段,有时候查询希望排除BLOB字段和集

Hibernate字段查询问题小记
我有一个实体类,包含了BLOB字段和集合属性字段,有时候查询希望排除BLOB字段和集合属性字段,有时候又希望只排除其中一个,这时问题就来了。
本来BLOB字段也可以设为lazy为true的,但是要做什么字节码强化,我想走走其他路子。
EntityBean

public class FormInfo {@Id@GeneratedValue(strategy=GenerationType.AUTO)//主键private long id;@Column(name="owner_id")//所有者主键private long ownerId;@Column(name="title_text",nullable=false)//标题private String titleText;@OneToMany(cascade={CascadeType.ALL}, fetch=FetchType.LAZY)@org.hibernate.annotations.Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)@JoinColumn(name="forminfo_id")//字段private Set<FieldInfo> fields;@Basic(fetch=FetchType.LAZY)@Lob@Column(name="source_code",columnDefinition="CLOB")//表单源码private String sourceCode;@Column(name="table_name",unique=true,nullable=false)//数据表名private String tableName;@Column(name="create_time")//创建时间private Timestamp createTime;@Column(name="update_time")//修改时间private Timestamp updateTime;//描述private String description;//删除标记private boolean deleted;//锁定标记private boolean locked; //完成标记private boolean completed;@Column(name="module_id")//模块主键private long moduleId;public FormInfo(){}//为HQL准备 日期类型改为java.util.Date类型,不然会报找不到构造方法异常public FormInfo(long id, long ownerId, String titleText,Set<FieldInfo> fields, String tableName, java.util.Date createTime,java.util.Date updateTime, String description, boolean deleted,boolean locked, boolean completed, long moduleId) {super();this.id = id;this.ownerId = ownerId;this.titleText = titleText;this.fields = fields;this.tableName = tableName;this.createTime = new java.sql.Timestamp(createTime.getTime());this.updateTime = new java.sql.Timestamp(updateTime.getTime());this.description = description;this.deleted = deleted;this.locked = locked;this.completed = completed;this.moduleId = moduleId;}public FormInfo(long id, long ownerId, String titleText, String tableName,java.util.Date createTime, java.util.Date updateTime, String description,boolean deleted, boolean locked, boolean completed, long moduleId) {super();this.id = id;this.ownerId = ownerId;this.titleText = titleText;this.tableName = tableName;this.createTime = new java.sql.Timestamp(createTime.getTime());this.updateTime = new java.sql.Timestamp(updateTime.getTime());this.description = description;this.deleted = deleted;this.locked = locked;this.completed = completed;this.moduleId = moduleId;}//...省略getter、setter}

BeanUtils
public class BeanUtils {private static Log logger = LogFactory.getLog(BeanUtils.class);/** * @param entityClass 实体类 * @param prefix 前缀 * @param fields 要过滤的字段列表 * @return 返回逗号分隔的entityClass的所有声明字段,排除filters指定的字段 */public static String getFieldNames(Class entityClass, String prefix, String... filters){Field[] fs = entityClass.getDeclaredFields();StringBuilder sb = new StringBuilder();String p = prefix != null ? prefix : "";for(int i=0;i<fs.length;i++){Field f = fs[i];if(contains(f.getName(), filters)){continue;}if(i>0)sb.append(",");sb.append(p + f.getName());}return sb.toString();}private static boolean contains( String f, String... fs){if(fs == null)return false;boolean result = false;for(int i=0; i<fs.length; i++){if(fs[i].indexOf(",") != -1){return contains(f, fs[i].split(","));}else{if(f.equals(fs[i])){result = true;break;}}}return result;}}


尝试一:HQL
super.find("select new FormInfo(" + BeanUtils.getFieldNames(FormInfo.class, "f.", "sourceCode") + ") from FormInfo f where f.completed = true");
生成SQL如下:
select
        forminfo0_.id as col_0_0_,
        forminfo0_.owner_id as col_1_0_,
        forminfo0_.title_text as col_2_0_,
        . as col_3_0_,
        forminfo0_.table_name as col_4_0_,
        forminfo0_.create_time as col_5_0_,
        forminfo0_.update_time as col_6_0_,
        forminfo0_.description as col_7_0_,
        forminfo0_.deleted as col_8_0_,
        forminfo0_.locked as col_9_0_,
        forminfo0_.completed as col_10_0_,
        forminfo0_.module_id as col_11_0_
    from
        t_bddz_forminfo forminfo0_
    inner join
        t_bddz_fieldinfo fields1_
            on forminfo0_.id=fields1_.forminfo_id
    where
        forminfo0_.completed=1
异常:org.hibernate.util.JDBCExceptionReporter,101 - ORA-00936: 缺失表达式
super.find("select new FormInfo(" + BeanUtils.getFieldNames(FormInfo.class, "f.", "sourceCode,fields") + ") from FormInfo f where f.completed = true");
生成SQL:
select
        forminfo0_.id as col_0_0_,
        forminfo0_.owner_id as col_1_0_,
        forminfo0_.title_text as col_2_0_,
        forminfo0_.table_name as col_3_0_,
        forminfo0_.create_time as col_4_0_,
        forminfo0_.update_time as col_5_0_,
        forminfo0_.description as col_6_0_,
        forminfo0_.deleted as col_7_0_,
        forminfo0_.locked as col_8_0_,
        forminfo0_.completed as col_9_0_,
        forminfo0_.module_id as col_10_0_
    from
        t_bddz_forminfo forminfo0_
    where
        forminfo0_.completed=1
异常:org.hibernate.QueryException: could not instantiate class [org.bsth.bddz.bean.FormInfo] from tuple
测试结果:失败,看来行不通了。


尝试二:用投影
public List<FormInfo> list(){
return super.findFieldsOfBean(BeanUtils.
getFieldNames(FormInfo.class, "", "sourceCode,fields").split(",")
, "completed", new Object[]{true});
}
一切正常
生成SQL:
select
        this_.id as y0_,
        this_.owner_id as y1_,
        this_.title_text as y2_,
        this_.table_name as y3_,
        this_.create_time as y4_,
        this_.update_time as y5_,
        this_.description as y6_,
        this_.deleted as y7_,
        this_.locked as y8_,
        this_.completed as y9_,
        this_.module_id as y10_
    from
        t_bddz_forminfo this_
    where
        this_.completed=?
如果改为:
public List<FormInfo> list(){
return super.findFieldsOfBean(BeanUtils.getFieldNames(FormInfo.class, "", "sourceCode").split(",")
, "completed", new Object[]{true});
}
并在findFieldsOfBean(...)方法中添加criteria.setFetchMode("fields", FetchMode.JOIN);
执行结果和SQL都同上一个一样,并没有把fields关联查询出来
看来在Hibernate中如果用了投影查询,FetchMode.JOIN就不起作用了

总结:目前还没解决即要排除BLOB字段又要关联集合属性字段的查询。

热点排行