Использование генераторов последовательностей гибернации вручную

StackOverflow https://stackoverflow.com/questions/1400371

Вопрос

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

Например, допустим, у меня есть Shipment сущность.В какой-то момент после создания посылки она отправляется.Как только товар отправляется, для него генерируется и присваивается номер манифеста.Номер манифеста выглядит примерно так M000009 (Где материал после 'M' - это дополненное слева значение из последовательности).

Было задано нечто подобное здесь , в SO , но я не поклонник этого решения, поскольку для его обслуживания требуется другая таблица, и мне кажется, что это странная взаимосвязь.

Кто-нибудь знает, возможно ли использовать что-то вроде hibernate MultipleHiLoPerTableGenerator как нечто отличное от генератора идентификаторов?

Если это невозможно, знает ли кто-нибудь о каких-либо библиотеках, которые обрабатывают это (либо используя hibernate, либо даже просто чистый JDBC).Я бы предпочел не писать это сам (и не иметь дело с предварительной выборкой значений, блокировкой и синхронизацией).

Спасибо.

Это было полезно?

Решение

Я думаю, что сложность вашей задачи зависит от того, должен ли ваш манифест number быть последовательным:

  • Если вам не нужны последовательные номера манифеста, тогда это счастливые дни, и вы можете использовать последовательность.
  • Если вам действительно нужны последовательные номера манифеста (или ваша база данных не поддерживает последовательности), то используйте таблицу идентификаторов с соответствующей блокировкой, чтобы каждая транзакция получала уникальное последовательное значение.

Тогда у вас есть 2 варианта, о которых я могу подумать:

  • напишите необходимый код JDBC на вашем клиенте, гарантируя (если номер манифеста является последовательным), что используемая транзакция совпадает с транзакцией для обновления базы данных.
  • используйте триггер для создания номера манифеста при выполнении соответствующего обновления.

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

Другие советы

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

Затем у меня был класс генератора последовательностей, который выполнял необходимый sql-запрос для извлечения и обновления значения последовательности для конкретной именованной последовательности.

Я использовал класс Dialect от hibernate, чтобы сделать это нейтральным к БД способом.

Я бы также "кэшировал" последовательности.Я бы увеличил сохраненное значение последовательности на большое число, а затем выделил бы их из выделенных последовательностей из моего класса generator.Если класс был уничтожен (т.е.завершение работы приложения), новый экземпляр генератора последовательностей запустился бы с сохраненным значением.(наличие пробела в моих порядковых номерах не имело значения)

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

public Long getManifestNumber() {
        final Object result = getHibernateTemplate().execute(new HibernateCallback() {
            public Object doInHibernate(Session sess) throws HibernateException, SQLException { 
                SQLQuery sqlQuery = sess.createSQLQuery("select MY_SEQUENCE.NEXTVAL from dual");
                sqlQuery.uniqueResult();
            }
        });
        Long toReturn;
        if (result instanceof BigDecimal) {
            toReturn = ((BigDecimal)result).longValue();
        }
        return toReturn;
    }
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top