powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / Hibernate generator без таблицы
25 сообщений из 34, страница 1 из 2
Hibernate generator без таблицы
    #39376209
ivanra
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Возникла задача генерировать последовательные уникальные id для нетабличных данных. В проекте используется hibernate, поэтому решено было использовать готовые механизмы. Как выяснилось, hibernate не предоставляет прямого доступа к генераторам. Копание в исходниках привело к такому коду:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
@TableGenerator(name="doc-generator", table="ids", pkColumnValue="seq_doc_generator", allocationSize=0x10)
// таблица-заглушка
@Entity
@Table(name="dummy_doc")
public class DummyDoc {
	private Long id;
	@Id
	@GeneratedValue(strategy=GenerationType.TABLE, generator="doc-generator")
	public Long getId() {
		return id;
	}
	public void setId(Long id) {
		this.id = id;
	}
}

/// и где-то в коде
	public Long nextId() {
		SessionFactoryImplementor sfi = (SessionFactoryImplementor)sessionFactory;
		IdentifierGenerator generator = sfi.getIdentifierGenerator(DummyDoc.class.getName());
		Session session = sessionFactory.getCurrentSession();
		Long value = (Long)generator.generate((SessionImplementor)session, null);
		return value;
	}


Что не нравится:
- если мы хотим переносимости, и чтобы всё само генерировалось, то надо объявлять
Код: xml
1.
<prop key="hibernate.hbm2ddl.auto">update</prop>

В этом случае генерируется ненужная таблица DUMMY_DOC, на каждый генератор - своя. Ну это ладно, можно обойти, не объявлять автоапдейт, и генерировать таблицу IDS руками, благо ничего там сложного нет
- использование непубличных интерфейсов SessionFactoryImplementor и SessionImplementor . Вот это неприятно, интерфейсы эти меняются, в разных версиях хибернейт они разные. Тоже можно полечить, вызвав соответствующие методы рефлексией, но как-то это некрасиво.

Есть ли более верное решение?
...
Рейтинг: 0 / 0
Hibernate generator без таблицы
    #39376219
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ivanra,

А почему нельзя тупо SQL выполнить для sequence?
...
Рейтинг: 0 / 0
Hibernate generator без таблицы
    #39376226
ivanra
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Можно, но не хочется разруливать диалекты.
Есть некоторая неопределеннсть с сервером, скорее всего это будет mssql или mysql, а там и генераторов то нет. Короче, хочется всё, что может поменяться, вынести в конфиги (аннотации это я для простоты привел), а там чтобы программа сама сгенерировала что надо, в зависимости от диалекта и заданной стратегии. У хибернейт это неплохо получается.
...
Рейтинг: 0 / 0
Hibernate generator без таблицы
    #39376234
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ivanra,

Можно в рантайме вытащить диалект и у него вызвать метод типа getSelectSequenceNextValString()
...
Рейтинг: 0 / 0
Hibernate generator без таблицы
    #39376255
ivanra
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
не лучше.
- Dialect всё равно надо вытаскивать через SessionFactoryImplementor
- sequence стратегия может быть неприменима к данному диалекту

Есть еще вариат с помощью deprecated метода получить фабрику генераторов, тогда можно обойтись без таблицы-пустышки, но писанины врядли будет меньше
Код: java
1.
2.
3.
		SessionFactoryImplementor sfi = (SessionFactoryImplementor)sessionFactory;
		IdentifierGeneratorFactory igf = sfi.getIdentifierGeneratorFactory();
		igf.createIdentifierGenerator(strategy, type, config)
...
Рейтинг: 0 / 0
Hibernate generator без таблицы
    #39376276
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ivanraВозникла задача генерировать последовательные уникальные id для нетабличных данных.
переведи задачу.
На момент разработки не знаете БД или что?
...
Рейтинг: 0 / 0
Hibernate generator без таблицы
    #39376285
ivanra
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Petro123ivanraВозникла задача генерировать последовательные уникальные id для нетабличных данных.
переведи задачу.
На момент разработки не знаете БД или что?
Не знаем, база будет та, которую заказчик использует в хранилище jackrabbit jcr, скорее всего mysql (sequence нет). В данном случае она идет как бесплатный довесок (какая-то база там обязательно должна быть).
Генератор, в принципе, можно было бы хранить просто в файле. Но не хочется разводить писанину с синхронизацией, а просто взять готовый отлаженный механизм. Генератор из hibernate - как вариант.
...
Рейтинг: 0 / 0
Hibernate generator без таблицы
    #39376303
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ivanraНе знаем, база будет та, которую заказчик использует в хранилище jackrabbit jcr, скорее всего mysql (sequence нет).

cq5 старой версии что ли?

jackrabbit это ж вроде самом по себе хранение данных альтернативное реляционному. каким боком тут база?
...
Рейтинг: 0 / 0
Hibernate generator без таблицы
    #39376312
ivanra
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
questioner jackrabbit это ж вроде самом по себе хранение данных альтернативное реляционному. каким боком тут база?
а Persistent Manager? Да, возможны варианты, но в данном случае будет обязательно использоваться Database PM
...
Рейтинг: 0 / 0
Hibernate generator без таблицы
    #39376346
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ivanraскорее всего mysql (sequence нет).
ну дак в половине баз нет сиквенсов, но есть счётчик-поле.
Как половина программистов на них работает и не жужжит?
Я по прежнему не понял проблему.
...
Рейтинг: 0 / 0
Hibernate generator без таблицы
    #39376347
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ivanraГенератор, в принципе, можно было бы хранить просто в файле.
смотри выше - есть тип поля счетчик.
...
Рейтинг: 0 / 0
Hibernate generator без таблицы
    #39376348
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
questionerjackrabbit это ж вроде самом по себе хранение данных альтернативное реляционному. каким боком тут база?
ну ТС даёт. Любая БД по ТЗ. Да ещё реляционная и НЕрялиционная).
...
Рейтинг: 0 / 0
Hibernate generator без таблицы
    #39376571
ivanra
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Petro123,
если хочется ответить, прошу внимательней читать вопрос, он в самом начале. Нужен проверенный генератор последовательных значений не для поля в таблице . Такой, как генератор/sequence в sql сервере - конкурентный, с сохранением состояния. Желательно настраиваемый через конфигурационные файлы.
По условиям задачи имеется SQL сервер, хотя это тут не главное. Я привел вариант решения с использованием механизмов хибернейт. Всего 5 строчек кода, но с хаками. Есть другие варианты?
...
Рейтинг: 0 / 0
Hibernate generator без таблицы
    #39376805
Alexey Tomin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ivanraВозникла задача генерировать последовательные уникальные id для нетабличных данных.

А рамках чего уникальные?
Например если в рамках хоста и может быть несколько инстансов то можно сделать такой вариант:

AtomicLong id = new AtomicLong(processPID * CONST1 + System.currentTimeMillis() * CONST2);
CONST1 и CONST2 подбираем так, чтобы заполнить старшые биты long'а.

Далее id.getAndIncrement() (он на тактик быстрее incrementAndGet()).

Если хостов несколько, но, к пимеру, на каждом один инстанс- заменяем processPID на hostId (не IP, а уникальный у тебя ID).
...
Рейтинг: 0 / 0
Hibernate generator без таблицы
    #39376808
Alexey Tomin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alexey TominAtomicLong id = new AtomicLong(processPID * CONST1 + System.currentTimeMillis() * CONST2);

Да, время надо уменьшить, конечно - NULL_DATE задаётся перед выкладкой в прод.
Код: java
1.
AtomicLong id = new AtomicLong(processPID * CONST1 + (System.currentTimeMillis() - NULL_DATE) * CONST2);
...
Рейтинг: 0 / 0
Hibernate generator без таблицы
    #39376863
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ivanraпрошу внимательней читать вопрос
нет это вы извольте писать постановку задачи, а не её решение.
Из постановки у вас 3 слова:
авторВозникла задача генерировать последовательные уникальные id для нетабличных данных.
всё остальное - это Ваше решение придуманное в голове.
Итого сначала:
- для кого ID?
Alexey Tomin уже выше вас спросил.
- в рамках чего уникальность?
...
Рейтинг: 0 / 0
Hibernate generator без таблицы
    #39376866
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ivanraНужен проверенный генератор последовательных значений не для поля в таблице . Такой, как генератор/sequence в sql сервере - конкурентный, с сохранением состояния.
опять двойка.
По своим свойствам, sequence ничем не отличается от типа поля счетчик.
Т.к. обычно на каждую таблу назначается только один sequence.
Т.е. он только повторяет или эмулирует поле счетчик.
...
Рейтинг: 0 / 0
Hibernate generator без таблицы
    #39376947
ivanra
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Petro123,
мне, например, неизвестен способ получения значения типа поля счетчик без вставки в таблицу. Было бы интересно увидеть (особенно - без таблицы).

Насчет уникальности ID: нужна уникальность в рамках хранилища (используется jackrabbit). Клиентов на данный момент 4, некоторые являются серверами приложений. Напрашивается решение в виде сервиса, который будет раздавать эти id, работающего на том же сервере, где хранилище. Но есть нюансы (некоторые клиенты сильно legacy, vb6 и delphi, чтоб было понятно на чем и когда они написаны).
Что касается реализации, то использование возможностей sql сервера лежит на поверхности. Если в сервере есть sequence - отлично, если нет, то берем TableGenerator, и там по возможности используется select for update - коллизий тоже не будет.
Да, hibernate в данном случае - это из пушки по воробью, но код очень короткий, надежный и покрывает все варианты использования. Кстати, выяснилось, что есть аннотация @Subselect, благодаря которой таблица-заглушка не генерируется.
Вот как выглядит это сейчас (пример с улучшенным TableGenerator)
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
// класс заглушка
@GenericGenerator(
		name = "doc_generator",
		strategy = "org.hibernate.id.enhanced.TableGenerator",
		parameters = {
				@Parameter(name = "segment_value", value = "seq_doc_generator"),
				@Parameter(name = "increment_size", value = "64"),
		})
@Entity 
@Subselect("")
public class DummyDoc {
	@Id @GeneratedValue(generator="doc_generator")
	private Long id;
}
// получение уникального значения
	@Transactional
	public Long nextId() {
		SessionFactoryImplementor sfi = (SessionFactoryImplementor)sessionFactory;
		IdentifierGenerator generator = sfi.getIdentifierGenerator(DummyDoc.class.getName());
		Session session = sessionFactory.getCurrentSession();
		return (Long)generator.generate((SessionImplementor)session, null);
	}
...
Рейтинг: 0 / 0
Hibernate generator без таблицы
    #39376964
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ivanraмне, например, неизвестен способ получения значения типа поля счетчик без вставки в таблицу. Было бы интересно увидеть (особенно - без таблицы).
ещё раз.
sequence - это то же поле счётчик в таблице. Только табла системная внутри БД. И наверх выведено API в виде sequence.
Т.е. вместо sequence можете свободно вставлять по одному полю в спец.таблицу.

ivanraНасчет уникальности ID: нужна уникальность в рамках хранилища (используется jackrabbit). Клиентов на данный момент 4, некоторые являются серверами приложений.
т.е. данные распределённые и есть гетерогенные транзакции?
ivanraНо есть нюансы (некоторые клиенты сильно legacy, vb6 и delphi, чтоб было понятно на чем и когда они написаны).
конкретнее.
- дельфи что? Делает JOIN с Id? Какая разница кто клиент?
...
Рейтинг: 0 / 0
Hibernate generator без таблицы
    #39376983
ivanra
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Petro123,
утверждение насчет хранения sequence в таблицах выдают вас как юниора, по крайней мере, в sql.
Но вопрос был в другом: как получить значение автоинкремента без вставки в таблицу? Конкретный код, например, в MSSQL. А без таблицы?
...
Рейтинг: 0 / 0
Hibernate generator без таблицы
    #39377005
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ivanraутверждение насчет хранения sequence в таблицах выдают вас как юниора, по крайней мере, в sql.
ваша боязнь использовать тип поля счетчик - тоже пионерство).
"Расписали".
...
Рейтинг: 0 / 0
Hibernate generator без таблицы
    #39377152
ivanra
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
:)
Кстати, а вот рояль в кустах. Чтобы получить значение автоинкремента без вставки записи, надо сначала её вставить, а затем откатить транзакцию.
Но всё равно требуется таблица.
...
Рейтинг: 0 / 0
Hibernate generator без таблицы
    #39377180
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ivanra,
упрямый))
Ты в оперативке ID держать будешь?
Надёжно?
...
Рейтинг: 0 / 0
Hibernate generator без таблицы
    #39377339
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ivanraPetro123,
утверждение насчет хранения sequence в таблицах выдают вас как юниора, по крайней мере, в sql.
Но вопрос был в другом: как получить значение автоинкремента без вставки в таблицу? Конкретный код, например, в MSSQL. А без таблицы?

какой кошмар невероятной продвинутости.

без таблицы нет надежно продвигаемого вперед и синхронизированного сиквенса.
Вы после выключения питания и перезапуска системы с какого значения продолжать изволите? не юниор вы наш
...
Рейтинг: 0 / 0
Hibernate generator без таблицы
    #39377360
Alexey Tomin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
boobyivanraPetro123,
утверждение насчет хранения sequence в таблицах выдают вас как юниора, по крайней мере, в sql.
Но вопрос был в другом: как получить значение автоинкремента без вставки в таблицу? Конкретный код, например, в MSSQL. А без таблицы?

какой кошмар невероятной продвинутости.

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

Существует масса способов решения этого. И "таблица значений последовательностей"- одно из них.
Как сделано в firebird/postgreSQL/mysql желающие могут посмотреть. Как в oracle/mssql/db2 - только гадать.
Так что умерьте пыл, горячие финские парни :)
...
Рейтинг: 0 / 0
25 сообщений из 34, страница 1 из 2
Форумы / Java [игнор отключен] [закрыт для гостей] / Hibernate generator без таблицы
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]