3

我的问题很简单:我有这个查询:

 SELECT * FROM TABLE t WHERE 
    (SELECT count(*) FROM TABLE tbis WHERE  TRUNC(t.date) = TRUNC(tbis.date))>1 ;

字段日期是时间戳。

如何使用标准 API 做到这一点?

我有这样的东西(trunc() 对我的数据库服务器有效,sql 请求有效。):

Criteria crit = session.createCriteria(Myclass.class, "t");
crit.createAlias("t.date", "dateT");

DetachedCriteria subcrit = DetachedCriteria.forclass(MyClass.class, "tbis");
subcrit.createAlias("tbis.date", "dateTbis");

subcrit.add(Restrictions.sqlRestriction("TRUNC(dateT) = TRUNC(dateTbis)"));

subcrit.setProjection(Projections.count("id"));

crit .add(Subqueries.gt(1, subcrit));
return crit.list();

不知何故,在日志中,我得到: org.hibernate.QueryException: not an association: date

我尝试了各种方法,但无法让它工作......

我试过了:

Criteria crit = session.createCriteria(Myclass.class, "t");

DetachedCriteria subcrit = DetachedCriteria.forclass(MyClass.class, "tbis");

subcrit.add(Restrictions.sqlRestriction("TRUNC(t.date) = TRUNC(tbis.date)"));

subcrit.setProjection(Projections.count("id"));

crit .add(Subqueries.gt(1, subcrit));

return crit.list();

生成的 SQL 条件为:

TRUNC(t.date) = TRUNC(tbis.date))

与日志:

18:34:04,461 WARN  [JDBCExceptionReporter] SQL Error: 904, SQLState: 42000
18:34:04,461 ERROR [JDBCExceptionReporter] ORA-00904: "T"."DATE": invalid identifier

18:34:04,461 WARN  [CriteriaAdapter] list exception: 
org.hibernate.exception.SQLGrammarException: could not execute query

Criteria crit = session.createCriteria(Myclass.class, "t");

DetachedCriteria subcrit = DetachedCriteria.forclass(MyClass.class, "tbis");

subcrit.add(Restrictions.sqlRestriction("TRUNC({t}.date) = TRUNC({tbis}.date)"));

subcrit.setProjection(Projections.count("id"));

crit .add(Subqueries.gt(1, subcrit));

return crit.list();

条件变为:

TRUNC({t}.date) = TRUNC({tbis}.date))

和日志:

18:36:28,206 WARN  [TxConnectionManager] Connection error occured: org.jboss.resource.connectionmanager.TxConnectionManager$TxConnectionEventListener@1b3febd3[state=NORMAL mc=org.jboss.resource.adapter.jdbc.xa.XAManagedConnection@4cb16baf handles=1 lastUse=1343284588160 permit=true trackByTx=true mcp=org.jboss.resource.connectionmanager.JBossManagedConnectionPool$OnePool@7f16f514 context=org.jboss.resource.connectionmanager.InternalManagedConnectionPool@3c34353b xaResource=org.jboss.resource.adapter.jdbc.xa.XAManagedConnection@4cb16baf txSync=null]
java.lang.NullPointerException
at oracle.jdbc.driver.T4C8Oall.getNumRows(T4C8Oall.java:1153)
[...]
at org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:208)

甚至:

Criteria crit = session.createCriteria(Myclass.class, "t");

DetachedCriteria subcrit = DetachedCriteria.forclass(MyClass.class, "tbis");

subcrit.add(Restrictions.sqlRestriction("TRUNC({t.date}) = TRUNC({tbis.date})"));

subcrit.setProjection(Projections.count("id"));

crit .add(Subqueries.gt(1, subcrit));

return crit.list();

与之前的结果相同。

我认为标准无法检测到子查询的别名...但是我必须访问该值,有什么解决方法吗?

4

1 回答 1

0

首先,如果您不应该将 { } 仅放在 sqlRestriction 中的别名周围,您可以尝试:

subcrit.add(Restrictions.sqlRestriction("TRUNC({t}.date) = TRUNC({tbis}.date)"));

如果您不想比较部分日期字段(如日期),但想查看整个日期字段是否相等,您可以让 Hibernate 像这样进行比较:

Restrictions.eq(t.date, tbis.date)

如果您想比较日期字段的一部分,我建议您参考这个问题。

于 2013-11-20T08:36:35.490 回答