Можно ли использовать аналитические функции в Hibernate?

Есть ли способ использовать sql-сервер, например аналитические функции в Hibernate?

Что-то вроде

select foo from Foo foo where f.x = max(f.x) over (partition by f.y)

Ответ 1

Вы выполняете собственный SQL-запрос.

Если вы используете JPA, синтаксис:

Query q = em.createNativeQuery("select foo.* from Foo foo " +
                               "where f.x = max(f.x) over " +
                               "(partition by f.y)", Foo.class);

Если вам нужно вернуть несколько типов, просмотрите аннотацию SQLResultSetMapping.

Если вы используете API Hibernate напрямую:

Query q = session.createSQLQuery("select {foo.*} from Foo foo " +
                                 "where f.x = max(f.x) over "+
                                 "(partition by f.y)");
q.addEntity("foo", Foo.class);

См. 10.4.4. Запросы в собственном SQL в документации Hibernate для более подробной информации.

В обоих API-интерфейсах вы можете передавать параметры, как обычно, с помощью setParameter.

Ответ 2

Другим подходом было бы использование отображения. См. Эту статью: https://forums.hibernate.org/viewtopic.php?f=1&t=998482

Я против использования собственных SQL-запросов в Hibernate... вы теряете преимущества наличия сопоставления: -)

Ответ 3

Да, вы можете, но вам нужно расширить диалоги спящего режима, как показано ниже:

import org.hibernate.dialect.Oracle10gDialect;

public class ExtendedDialect extends Oracle10gDialect{
    public ExtendedDialect()
    {
           super();
           registerKeyword("over");
           registerKeyword("partition");
    }
}

Как только этот класс находится в вашем пути к классам, вам нужно будет указать hibernate использовать его вместо исходного диалекта (в данном случае Oracle10gDialect). Я не уверен, какие рамки вы используете, но в случае Spring вы можете использовать следующее свойство в LocalContainerEntityManagerFactoryBean:

        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                <property name="databasePlatform" value="path.to.dialect.ExtendedDialect" />
            </bean>
        </property>

Затем вы можете использовать over и partition в @Formula annotations, @Where аннотации и другие функции спящего режима, не запутывая спящий режим.