【发布时间】:2013-08-11 11:45:28
【问题描述】:
我正忙于使用 hibernate 4.2.2.Final 和 Spring 3.2.3.RELEASE 编写应用程序。我使用日志框架 log4jdbc-remix (0.2.7) 来记录对数据库的所有 sql 调用。我正在使用休眠条件来生成 SQL 语句。在一种情况下,我正在生成一条 SQL 语句,当我在数据库本身 (DB/2) 上执行它时返回结果,只需从日志输出中复制粘贴即可。在休眠中,结果列表是空的(相同的查询)。
方法(我确实将变量的名称更改为更“通用的英语”名称):
@Override
public List<PersonId> getActiveNumbers(SpecialNumber specialumber) {
final Criteria criteria = this.getCurrentSession().createCriteria(Person.class);
criteria.add(Restrictions.eq("specialNr", specialNumber));
criteria.setProjection(Projections.projectionList()
.add(Projections.property("id.baseNr"))
.add(Projections.property("id.subNr")));
criteria.add(Subqueries.propertiesIn(new String[] { "id.baseNr", "id.subNr" },
isActive()));
criteria.setResultTransformer(Transformers.aliasToBean(PersonId.class));
return (List<PersonId>) criteria.list();
}
private DetachedCriteria isActive() {
DetachedCriteria isActive = DetachedCriteria.forClass(PersonSpecific.class);
isActive.add(LocalDateComposite.lessThanOrEqual("date", LocalDate.now()));
isActive.add(Restrictions.or(Restrictions.eq("dateCancel", null),
Restrictions.ge("dateCancel", LocalDate.now())));
isActive.setProjection(Projections.projectionList()
.add(Projections.property("id.baseNr").as("baseNr"))
.add(Projections.property("id.subNr").as("subNr")));
return isActive;
}
但是,当我删除该行时
criteria.add(Restrictions.eq("specialNr", specialNumber));
hibernate 确实会生成一个结果列表。子查询“isActive”返回具有正确值的正确查询(根据日志,当我删除上述行时也是如此)。
'specialNr' 是 'specialNumber' 类型,我有一个自定义 UserType:
public class SpecialNumberUserType extends AbstractUserType implements UserType {
private static final int[] TYPES = { Types.BIGINT };
[...]
@Override
public int[] sqlTypes() {
return TYPES;
}
@Override
public Class<?> returnedClass() {
return SpecialNumber.class;
}
@Override
public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner)
throws HibernateException, SQLException {
if (rs.wasNull()) {
return null;
}
return new specialNumber(rs.getLong(names[0]));
}
@Override
public void nullSafeSet(PreparedStatement st, Object value, int index,
SessionImplementor session) throws HibernateException, SQLException {
if (null == value) {
st.setLong(index, 0L);
} else {
st.setLong(index, ((SpecialNumber) value).getValue());
}
}
}
我不明白为什么 hibernate 确实会生成正确的 sql,但无法获取正确的结果。我确实在其他表和查询中使用了“specialNumber”,它在其他查询中也有效。只有在这种特殊情况下,hibernate 才不会获取结果。有任何想法吗?感觉好像自定义用户类型 SpecialNumberUserType 有问题,但我不知道是什么问题,因为生成的 sql 显示了正确的值,并且它适用于使用相同“specialNumber”类的其他 sql 语句。
-- 编辑:
我忘了提一下:当我对内存中的测试数据库 (hsqldb) 运行相同的方法时,我确实得到了预期的结果。所以,总结一下:
- 生成的 sql 正常,值正确(检查日志);
- 直接在数据库(db/2终端)上运行生成的sql,得到了预期的结果;
- 对内存数据库运行方法“getActiveNumbers”,我得到了预期的结果;
- 对真实数据库运行方法“getActiveNumbers”,我得到一个空列表,这不是预期的结果。
- 运行相同的方法,但具有行 'criteria.add(Restrictions.eq("specialNr", specialNumber));'删除后,我确实得到了该查询的预期结果(这是相当多的行);
- 使用与另一个类的属性相同的“SpecialNumber”类对真实数据库运行其他查询(使用休眠条件)确实有效 - 此处未显示代码,但非常相似,具有类似“criteria.add”的行(Restrictions.eq("specialNr", specialNumber));'.
我很困惑……
-- EDIT_II:
我正在尝试让它与 hql 查询一起使用。同样非常奇怪的问题,我只关注“specialNumber”:
final Query query = this.getCurrentSession().createQuery(
"select * from Person where specialNumber = 436260171");
给出预期的结果。 (本例中有 2 条记录)。当我将其更改为:
final Query query = this.getCurrentSession().createQuery(
"select * from Person where specialNumber = :specialNumber");
query.setLong("specialNumber", 436260171L);
或
query.setParameter("specialNumber", new SpecialNumber(436260171L));
我又得到一个空列表。所以,使用一个参数,突然间,它不再起作用了。我不明白:p。
【问题讨论】:
-
我也很疑惑。不知道发生了什么,但我在黑暗中开了枪。检查数据库权限。因此,当您直接查询数据库时,请确保您使用的是相同的凭据(之所以这么说是因为我们大多数人都使用超级帐户直接连接到数据库...)。除此之外,不知道。
-
感谢您的回答,但是是的,凭据还可以。我做了更多测试:见 EDIT_II
标签: sql spring hibernate criteria usertype