Использование генераторов последовательности Hibernate вручную - PullRequest
3 голосов
/ 09 сентября 2009

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

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

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

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

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

Спасибо.

Ответы [ 3 ]

1 голос
/ 09 сентября 2009

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

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;
    }
1 голос
/ 09 сентября 2009

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

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

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

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

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

1 голос
/ 09 сентября 2009

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...