Есть ли способ заставить Hibernate использовать буквальные значения, а не связывать переменные? - PullRequest
7 голосов
/ 24 ноября 2011

В Oracle у меня есть секционированная таблица.Разделы имеют разные размеры и имеют разное распределение данных.

Я хотел бы иметь операторы SQL проблемы гибернации, которые включают литеральное значение для столбца ключа раздела, а не переменную связывания.Конечно, он должен использовать переменные связывания для любых других значений.

Использование литерала для ключа раздела позволит Oracle разработать план, относящийся к известному разделу и собранной статистике.Это также может быть полезно для столбцов, которые имеют гистограмму для искаженных данных.

Было бы предпочтительно указать это в сущности, в противном случае нам потребуется делать это в каждом запросе.Есть ли способ сделать это в hibernate?

Мы на hibernate 3.6.1, используя Oracle 10g Dialect.

Если нет способа сделать это изначально в Hibernate, могу ли ясоздать тип пользователя или диалект или что-то, чтобы это произошло?

Ответы [ 3 ]

1 голос
/ 02 декабря 2011

Вы можете использовать namedNativeQuery Вот пример реализации.

Класс сущности

@Entity
@Table(catalog = DBCatalog)
@org.hibernate.annotations.NamedNativeQuery(name="partitionTR1",query ="SELECT * FROM DATAMARTTRANSACTIONHISTORY PARTITION (tr1) where id=?",resultClass=DataMartTable.class)
public class DataMartTransactionHistory implements TransactionHistory {
    @Id
    @Column
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    @Enumerated(EnumType.ORDINAL)
    private TransactionStatus transactionStatus;
... other props...
}

и вот реализация dao.

public DataMartTransactionHistory findDataMartTransactionHistoryTR1(Long id) {
    Query namedQuery = getSessionFactory().getCurrentSession().getNamedQuery("partitionTR1");
    namedQuery.setLong(0, id);
    return (DataMartTransactionHistory)namedQuery.list().get(0);
}
1 голос
/ 29 ноября 2011

Нет, литеральные значения не поддерживаются в Hibernate. Я сомневаюсь, что вы можете сделать обходной путь, но я думаю, что вы ищете другое решение.

0 голосов
/ 30 ноября 2011

В качестве обходного пути вы можете установить уникальный комментарий на каждом «интересном» сайте вызовов, чтобы вы могли контролировать просмотр переменных привязки Oracle.

...
query = session.createQuery("...");
...
query.setString("param1", "FOO");
query.setInteger("param2", param2Value);
...
query.setComment("param1 = \"FOO\"");
...

Таким образом, оптимизатор увидит "FOO"в трудное время (как обычно).В будущих вызовах Oracle будет искать точную копию SQL для повторного использования плана выполнения.Поскольку комментарий делает запрос фактически уникальным, это даст вам тот же план выполнения, который был рассчитан с помощью "FOO", а не любое другое значение param1.

. Вы должны быть осторожны, так как оптимизатор такжеиспользуйте значение param2Value для расчета плана выполнения, чтобы оно могло помешать.Но я думаю, что хотя бы стоит попробовать.

...