Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java EE (J2EE) и Spring > strategy=GenerationType


Автор: Samotnik 17.5.2011, 00:19
Привет. 
Стоит задача, сделать так, чтобы приложение работало, хотя бы в двух БД: MySQL, Oracle.
Необходимо выбрать стратегию для генерирования id, определить GenerationType. Их 4: AUTO, IDENTITY, SEQUENCE, TABLE.
IDENTITY - работает в MySQL, но не работает с Ораклом.
SEQUENCE - работает с Oracle, но не работает с MySQL.
AUTO - не подходит.
остается TABLE.
Вопрос, пользовался ли кто-нибудь этим типом, были ли проблемы? Проблема в том, что до этого приложение крутилось на Мускуле, и отлично генрились id по типу IDENTITY. Сейчас пришлось использовать TABLE. И посыпались очень странные ошибки. При обычном запросе через критерию, выкидывается:
java.lang.OutOfMemoryError: Java heap space
Caused by: com.mysql.jdbc.PacketTooBigException: Packet for query is too large (8800390 > 1048576). You can change this value on the server by setting the max_allowed_packet' variable.

Почему outofmemory выстреливает не понимаю, ведь запись содержит всего 3 значения (id, name, surname).
Есть одно обстоятельство. TABLE, странно генерирует id. По начлау нормально - с 0 и по очереди, но если удалить несколько записей, изменить существующие, и затем создавать новые, то айдишники получаются сумасщедшие, типа '32768' или '65133'
Получается что в БД такие записи:
id, name, surname
(0, Andrew, B)
(1, Dima, C)
(4, Vasja, P)
(34567, Olja G)
(67192, July S)
Может быть в этом проблема ?

Автор: carper 17.5.2011, 09:23
Цитата(Samotnik @  17.5.2011,  00:19 Найти цитируемый пост)
Необходимо выбрать стратегию для генерирования id


Несколько идей: 

0. id - это штука для машины, поэтому id не может быть "сумасшедшим" id=1, ничем не лучше id=23451234, последнее дольше набирать при отладке, но программист как-нибудь справится. smile 

1. Использовать UUID

2. Вроде как у народа, сам не проверял, работает новый генератор:
org.hibernate.id.enhanced.SequenceStyleGenerator

On databases which support SEQUENCEs, SequenceStyleGenerator will in fact use a SEQUNCE as the value generator; for those database which do not support SEQUENCEs, it will instead use a single-row table as the value generator, but with the same exact charecteristics as a SEQUENCE value generator (namely it deals with the "sequence table" in a separate transaction at all times).

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

Кстати, именно таким образом получится самое что ни на есть переносимое приложение - всё равно тип колонки с id  (хотя бы по максимальному размеру, или наименованию типа поля) в разных базах может быть разным, вот и добавьте при генерации таблиц еще и нормальный генератор id.

Если Hibernate позволяет изощряться с id разными способами это совсем не значит, что это НАДО использовать.

Генерал Ватутин говаривал: «Характер, как подштанники – надо иметь, но выставлять наружу нехорошо!».

Автор: MisterCleric 17.5.2011, 09:56
Привет.
Попробуй использовать такое:
Код

 @GenericGenerator(name="nextVal", strategy="sequence-identity",
  parameters={@Parameter(value="sequenceName", name="sequence")})
 @GeneratedValue(generator="nextVal") 
@Id 


Если не получится, то предлагаю такое решение:
1. Используем паттерн "Стратегия"
2. Реализовываем композицию генераторов, где наш класс будет wrapper над целевым
3. Конфигурим ту стратегию (один из делегатов в нашей композиции) в зависимости от Dialect, чтобы не перекомпиливать под разные БД. Это возможно через имплементацию org.hibernate.id.Configurable
4. И проставляем проперти delegate в тот инстанс IdentifierGenerator, который у нас получился в методе configure

А дальше используем все тот же  @GenericGenerator, только свойство strategy должно быть равно полному имени класса

Автор: Samotnik 17.5.2011, 18:28
carper, MisterCleric, спасибо, вопрос с id решил. Но java.lang.OutOfMemoryError: Java heap space по прежнему выстреливает.
Но для этого новую тему нужно создать

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)