I have a problem using JPA with Oracle and grouping by hour. Here's the scenario: I have an entiry named EventData. This entity has a java.util.Date field named startOfPeriod. This field maps in a table field of datatype DATE. The query I'm using is something like:
select min(ed.startOfPeriod) as eventDate,
(...)
from
Event e inner join e.eventDatas ed
(...)
group by
year(ed.startOfPeriod),
month(ed.startOfPeriod),
day(ed.startOfPeriod),
hour(ed.startOfPeriod)
order by 1
If I remove the group by "hour(ed.startOfPeriod)" it works fine (it doesn't produce any errors but it doesn'to do what I want). When I insert this group by clause it makes this exception:
Caused by: java.sql.SQLException: ORA-30076: campo de extração inválido para origem de extração
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:331)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:288)
at oracle.jdbc.driver.T4C8Oall.receive(T4C8Oall.java:745)
at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:219)
at oracle.jdbc.driver.T4CPreparedStatement.executeForDescribe(T4CPreparedStatement.java:813)
at oracle.jdbc.driver.OracleStatement.executeMaybeDescribe(OracleStatement.java:1049)
at oracle.jdbc.driver.T4CPreparedStatement.executeMaybeDescribe(T4CPreparedStatement.java:854)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1154)
at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3370)
at oracle.jdbc.driver.OraclePreparedStatement.executeQuery(OraclePreparedStatement.java:3415)
at org.apache.commons.dbcp.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:92)
at org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:208)
at org.hibernate.loader.Loader.getResultSet(Loader.java:1812)
at org.hibernate.loader.Loader.doQuery(Loader.java:697)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:259)
at org.hibernate.loader.Loader.doList(Loader.java:2232)
Analysing the error code, it happens when "The extract source does not contain the specified extract field.". But the source of extraction (the startOfPeriod field) is of datatype DATE (which has an hour part).
The same code works like a charm in SQL Server.
Anyone knows what is going on?
Tnhks!
I didn't convert all my DATE
fields to TIMESTAMP
ones.
Instead, I extended the Oracle's dialect to rewrite the hour
function.
Like that:
public class Oracle9Dialect extends org.hibernate.dialect.Oracle9Dialect
{
public Oracle9Dialect()
{
super();
registerFunction("hour", new SQLFunctionTemplate(Hibernate.INTEGER, "to_number(to_char(?1, 'hh24'))"));
}
}
Using this dialect (org.hibernate.dialect.Dialect
), the hour
function will not use the ANSI hour
function (extract(hour from <FIELD>)
). It will use to_number(to_char(<FIELD>, 'hh24'))
instead.
The bad thing is that it always use the custom function (even when it doesn't need to be used, like with a TIMESTAMP
field).
This is what I did to solve my problem.