|
|
|
JPA (Hibermate) custom sequence
|
|||
|---|---|---|---|
|
#18+
Добрый день, Передо мной стоит задача автоматически генерировать идентификаторы вида "ГГГГ/XXXX", где ГГГГ - номер календарного года, а XXXX - номер по порядку в рамках календарного года. С 1го января нумерация XXXX должна обнуляться. Сгенерированные идентификаторы нужно хранить в БД (Oracle в моем случае). Насколько я понял из документации, с помощью @GenericGenerator можно реализовать логику формирования идентификатора на Java. Но в такой реализации не понятно, как синхронизировать запросы от разных клиентов? Возможно ли это в принципе? Альтернативно, как я понимаю, логику формирования идентификатора можно реализовать на стороне БД, что, теоретически, должно решить проблему синхронизации. Я плохо знаком с БД, поэтому хочу уточнить: 1. Возможна ли реализация описанной мной логики на уровне БД? (как я понял, нужно создать свой sequence) 2. Требуются ли какие-то доп. меры для обеспечения синхронизации запросов? 3. Правильно ли я понял, что созданный sequence можно будет замапить в Hibernate с помощью аннотаций @GeneratedValue и @SequenceGenerator? Заранее спасибо за помощь. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.12.2013, 15:20:01 |
|
||
|
JPA (Hibermate) custom sequence
|
|||
|---|---|---|---|
|
#18+
abc_da, смысл задачи ускользает. Идентификатор в БД - это число, а не строка со слэшем. Тогда его можно использовать как первичный ключ и использовать в запросах. ....... Да, вопрос синхронизации при методе "в БД" не стоит. Вне БД, вопрос не стоит, если все ходят через одни ворота - хибер. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.12.2013, 20:09:54 |
|
||
|
JPA (Hibermate) custom sequence
|
|||
|---|---|---|---|
|
#18+
Petro123, спасибо за ответ. Petro123смысл задачи ускользает. Идентификатор в БД - это число, а не строка со слэшем. Тогда его можно использовать как первичный ключ и использовать в запросах. Задача в том, чтобы генерировать номера по порядку в рамках календарного года. Строка со слэшем - это представление. Как я понимаю, можно сделать составной первичный ключ из полей "год" и "номер по порядку". Вопрос в том, как обеспечить автоинкремент с обнулением при переходе на новый год. Petro123Вне БД, вопрос не стоит, если все ходят через одни ворота - хибер. В моем случае используется кластеризация, клиенты будут ходить из разных jvm. Можно ли при генерации порядкового номера вне БД обеспечить синхронизацию на уровне БД? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.12.2013, 21:12:39 |
|
||
|
JPA (Hibermate) custom sequence
|
|||
|---|---|---|---|
|
#18+
abc_daЗадача в том, чтобы генерировать номера по порядку в рамках календарного года. Строка со слэшем - это представление. Как я понимаю, можно сделать составной первичный ключ из полей "год" и "номер по порядку". Вопрос в том, как обеспечить автоинкремент с обнулением при переходе на новый год. ещё раз - Зачем так нужно? Почему номер паспорта не состоит из года регистрации? Или ИНН? Представление машине или ЭВМ не нужно. Оно только для человека. Для него нет проблем сделать такое СПРАВОЧНОЕ доп-поле. Но это не PK ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.12.2013, 22:12:35 |
|
||
|
JPA (Hibermate) custom sequence
|
|||
|---|---|---|---|
|
#18+
abc_daЯ плохо знаком с БД, поэтому хочу уточнить: на уровне БД вопрос в форум БД. На уровне АппСервера - хибера - вопрос в данной ветке. Работать будет и так и так. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.12.2013, 22:15:54 |
|
||
|
JPA (Hibermate) custom sequence
|
|||
|---|---|---|---|
|
#18+
Petro123на уровне БД вопрос в форум БД. На уровне АппСервера - хибера - вопрос в данной ветке. В форуме по Oracle уже задал свой вопрос . Здесь хотелось бы услышать о возможности реализации на уровне Hibernate (предпочтительный для меня вариант). Petro123ещё раз - Зачем так нужно? Почему номер паспорта не состоит из года регистрации? Или ИНН? Представление машине или ЭВМ не нужно. Оно только для человека. Для него нет проблем сделать такое СПРАВОЧНОЕ доп-поле. Но это не PK Чтобы было понятнее, чего я хочу добиться, приведу пример из реальной жизни: Допустим, вы разрабатываете систему документооборота. Каждый документ имеет свой уникальный номер. В организации принято нумеровать документы одного типа по порядку в рамках календарного года, в формате "Год/номер по порядку". Нужно автоматизировать выдачу таких номеров. Я не ставлю своей целью забубенивать в идентификатор год регистрации вместе со слэшем. "ГГГГ/ХХХХ" - это конечная цель, представление, которое я смогу сформировать налету, имея 2 поля в БД: "год" и "порядковый номер". Как запихнуть в БД год - я понимаю. Как реализовать счетчик для выдачи номеров по порядку в рамках года - нет. Разбивая задачу на части, я вижу следующие проблемы: 1. Как обеспечить обнуление счетчика 1го января? 2. Как обеспечить синхронизацию, учитывая, что запросы к БД могут идти из разных JVM, а каждый запрос должен гарантированно получить уникальный порядковый номер? Как можно решить поставленную задачу с применением Hibernate? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.12.2013, 01:23:50 |
|
||
|
JPA (Hibermate) custom sequence
|
|||
|---|---|---|---|
|
#18+
А что мешает "обнулять" счетчик 31.12 в 23:59? Например, скриптом по системному рассписанию или руками (можно забыть запустить)? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.12.2013, 01:41:58 |
|
||
|
JPA (Hibermate) custom sequence
|
|||
|---|---|---|---|
|
#18+
olexande, мне хотелось бы, чтобы решение было максимально локализовано в одном месте и не требовало бы за собой ухода. Но если иначе никак - придется обнулять по расписанию, да. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.12.2013, 02:34:45 |
|
||
|
JPA (Hibermate) custom sequence
|
|||
|---|---|---|---|
|
#18+
abc_da, Вы не сказали что делает бизнес при вводе нового документа задним числом? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.12.2013, 13:30:20 |
|
||
|
JPA (Hibermate) custom sequence
|
|||
|---|---|---|---|
|
#18+
Petro123Вы не сказали что делает бизнес при вводе нового документа задним числом? В моем случае такой сценарий невозможен. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.12.2013, 15:52:24 |
|
||
|
JPA (Hibermate) custom sequence
|
|||
|---|---|---|---|
|
#18+
abc_daДопустим, вы разрабатываете систему документооборота. Каждый документ имеет свой уникальный номер. В организации принято нумеровать документы одного типа по порядку в рамках календарного года, в формате "Год/номер по порядку". Нужно автоматизировать выдачу таких номеров. Вы изобретаете велосипед. Не делает так никто "в системах документооборота". Номера документов виде "Год/месяц/номер по порядку/еще_что_нибудь" генерируются в момент создания документа как значения "по умолчанию" которые можно поменять при подтверждении создания документа (потому что часто их приходится "настраивать" вручную.... документооборот штука непредсказуемая). Очередной номер документа за _требуемый_ год подставляется или выборкой максимального значения из существующих записей (например, у вас может быть отдельный столбец "год" и отдельный "номер в году") или из отдельного хранилища суммарных записей за указанный год (тоже есть варианты, от задачи зависит). Но это все делает дополнительная бизнес-логика, а не генератор, привязанный к таблице. Это не имеет никакого отношения к PK в БД. Хватит велосипедов. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.12.2013, 17:41:56 |
|
||
|
JPA (Hibermate) custom sequence
|
|||
|---|---|---|---|
|
#18+
_newcomer_abc_daДопустим, вы разрабатываете систему документооборота. Каждый документ имеет свой уникальный номер. В организации принято нумеровать документы одного типа по порядку в рамках календарного года, в формате "Год/номер по порядку". Нужно автоматизировать выдачу таких номеров. Вы изобретаете велосипед. Не делает так никто "в системах документооборота". Номера документов виде "Год/месяц/номер по порядку/еще_что_нибудь" генерируются в момент создания документа как значения "по умолчанию" которые можно поменять при подтверждении создания документа (потому что часто их приходится "настраивать" вручную.... документооборот штука непредсказуемая). _newcomer_, у меня есть вполне конкретное требование, которое я привел в первом после. Далее я проиллюстрировал это требование в контексте системы документооборота, предполагая, что так получится нагляднее. К счастью, передо мной не стоит задача реализации системы документооборота. Прошу прощения, если это не было очевидно из моих сообщений. _newcomer_Очередной номер документа за _требуемый_ год подставляется или выборкой максимального значения из существующих записей (например, у вас может быть отдельный столбец "год" и отдельный "номер в году") или из отдельного хранилища суммарных записей за указанный год (тоже есть варианты, от задачи зависит). Но это все делает дополнительная бизнес-логика, а не генератор, привязанный к таблице. Согласен, это кажется мне отличным решением. Давайте в этом топике обсудим возможность такой реализации. Несколько постов назад я задал вопрос, который в свете описанного решения актуален: abc_da2. Как обеспечить синхронизацию, учитывая, что запросы к БД могут идти из разных JVM, а каждый запрос должен гарантированно получить уникальный порядковый номер? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.12.2013, 13:55:26 |
|
||
|
JPA (Hibermate) custom sequence
|
|||
|---|---|---|---|
|
#18+
Ну на самом деле автор не просил генерировать PK, а просил генерировать идентификатор документа, так что не стоит нагнетать. Напрашивается некий синхронизированный метод, в котором номера будут выдаваться строго последовательно. Возможно, реализованный в веб-сервисе, если приложений много ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.12.2013, 14:10:17 |
|
||
|
JPA (Hibermate) custom sequence
|
|||
|---|---|---|---|
|
#18+
abc_da1. Возможна ли реализация описанной мной логики на уровне БД? Конечно. abc_da (как я понял, нужно создать свой sequence) Не думаю, что это лучший вариант. abc_da2. Требуются ли какие-то доп. меры для обеспечения синхронизации запросов? Если реализовать на Java, то конечно нужны блокировки. Если на базе данных, то можно попробовать обойтись тразнакционностью до тех пор пока база не станет распределенной. abc_da3. Правильно ли я понял, что созданный sequence можно будет замапить в Hibernate с помощью аннотаций @GeneratedValue и @SequenceGenerator? Да, типа того. У нас реализован альтернативный оптимистичный подход. Делается запрос вида SELECT MAX, так чтобы получить следующий номер для текущего Года и Месяца. Потом с этим сущность персистится в базу. Если при этом вылетает Unique Constraint Violation, то номер пересоздаётся, сущность пересохраняется. Это простое и надежное решение. Единственный его недостаток это производительность. Нужно смотреть на сколько часто у вас этот ID должен генерироваться. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.12.2013, 14:18:50 |
|
||
|
JPA (Hibermate) custom sequence
|
|||
|---|---|---|---|
|
#18+
BlazkowiczДелается запрос вида SELECT MAX, так чтобы получить следующий номер для текущего Года и Месяца. Потом с этим сущность персистится в базу. Если при этом вылетает Unique Constraint Violation, то номер пересоздаётся, сущность пересохраняется. Это простое и надежное решение. Единственный его недостаток это производительность. Нужно смотреть на сколько часто у вас этот ID должен генерироваться. Спасибо большое, мне такое решение подойдет. Подскажите, куда лучше прикрутить вызов логики заполнения поля, в @PrePersist или через @GeneratedValue и @GenericGenerator? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.12.2013, 15:00:20 |
|
||
|
JPA (Hibermate) custom sequence
|
|||
|---|---|---|---|
|
#18+
Я вот подумал ещё немного. Идеальным ведь вариантом будет запрос вида INSERT с SELECT подзапросом MAX() + 1. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.12.2013, 15:15:53 |
|
||
|
JPA (Hibermate) custom sequence
|
|||
|---|---|---|---|
|
#18+
BlazkowiczЯ вот подумал ещё немного. Идеальным ведь вариантом будет запрос вида INSERT с SELECT подзапросом MAX() + 1. У нас просто логика генерации такого ID гораздо более замороченая, поэтому решили оставить в Java. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.12.2013, 15:16:53 |
|
||
|
JPA (Hibermate) custom sequence
|
|||
|---|---|---|---|
|
#18+
на самом деле решения вида SELECT MAX при некоторых настройках транзакций могут приводить к дедлокам в базе. Лучше уж сериализацию через синхронизируемый метод ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.12.2013, 15:27:55 |
|
||
|
JPA (Hibermate) custom sequence
|
|||
|---|---|---|---|
|
#18+
BlazkowiczЯ вот подумал ещё немного. Идеальным ведь вариантом будет запрос вида INSERT с SELECT подзапросом MAX() + 1. Такое можно сделать на JPA/Hibernate? +мне ведь еще с нуля каждый год нужно начинать. abc_daПодскажите, куда лучше прикрутить вызов логики заполнения поля, в @PrePersist или через @GeneratedValue и @GenericGenerator? Почитал, пишут, что по спецификации @GeneratedValue не предназначен для non-PK полей. Выходит, @PrePersist - мой вариант? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.12.2013, 15:31:05 |
|
||
|
JPA (Hibermate) custom sequence
|
|||
|---|---|---|---|
|
#18+
abc_daТакое можно сделать на JPA/Hibernate? +мне ведь еще с нуля каждый год нужно начинать. SELECT MAX(SUBSTRING(columnName, ...)) ... + @SQLInsert(sql="... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.12.2013, 15:35:27 |
|
||
|
JPA (Hibermate) custom sequence
|
|||
|---|---|---|---|
|
#18+
ivanraЛучше уж сериализацию через синхронизируемый метод что это такое? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.12.2013, 15:39:19 |
|
||
|
JPA (Hibermate) custom sequence
|
|||
|---|---|---|---|
|
#18+
ivanraна самом деле решения вида SELECT MAX при некоторых настройках транзакций могут приводить к дедлокам в базе. Интересно. Спасибо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.12.2013, 15:44:05 |
|
||
|
JPA (Hibermate) custom sequence
|
|||
|---|---|---|---|
|
#18+
abc_daivanraЛучше уж сериализацию через синхронизируемый метод что это такое? Serializable Transaction, вероятно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.12.2013, 15:44:25 |
|
||
|
JPA (Hibermate) custom sequence
|
|||
|---|---|---|---|
|
#18+
Blazkowiczabc_daТакое можно сделать на JPA/Hibernate? +мне ведь еще с нуля каждый год нужно начинать. SELECT MAX(SUBSTRING(columnName, ...)) ... + @SQLInsert(sql="...Идея понятна, спасибо. Но как обеспечить "номер по порядку в рамках календарного года" с помощью SQL-выражения - не совсем понятно. Можно сделать что-то вроде MAX(SUBSTRING(columnName, ...) WHERE год=текущий год и default=0, если MAX вернул пустое множество? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.12.2013, 15:45:32 |
|
||
|
JPA (Hibermate) custom sequence
|
|||
|---|---|---|---|
|
#18+
abc_daНо как обеспечить "номер по порядку в рамках календарного года" с помощью SQL-выражения - не совсем понятно. Можно сделать что-то вроде MAX(SUBSTRING(columnName, ...) WHERE год=текущий год и default=0, если MAX вернул пустое множество? Ну, вы же программист. Детали-то уже очевидны. Да, через WHERE делать выборку за нужный год или месяц. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.12.2013, 15:47:40 |
|
||
|
|

start [/forum/topic.php?fid=59&msg=38501455&tid=2127969]: |
0ms |
get settings: |
6ms |
get forum list: |
10ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
174ms |
get topic data: |
7ms |
get forum data: |
2ms |
get page messages: |
41ms |
get tp. blocked users: |
1ms |
| others: | 194ms |
| total: | 441ms |

| 0 / 0 |
