Уникальный идентификатор в JPA (мультитенант) - PullRequest
0 голосов
/ 20 сентября 2011

В настоящее время я работаю над мультитенантным приложением, использующим JPA (Hibernate). Для некоторых таблиц мне нужен порядковый номер, уникальный для каждого арендатора. Из-за этого я не могу использовать @GeneratedValue для этих полей. Я решил использовать дополнительную сущность под названием Sequence с полем long, помеченным @Version. При запросе нового идентификатора я делаю следующее:

Sequence seq = em.find(Sequence.class, pk, LockModeType.PESSIMISTIC_FORCE_INCREMENT);
long nextId = seq.id;

Это работает, пока я не запускаю приложение дважды. Тогда я получаю следующее исключение:

Исключение в потоке "main" javax.persistence.OptimisticLockException: org.hibernate.StaleObjectStateException: строка была обновлена ​​или удалена другая транзакция (или сопоставление несохраненного значения было неверным)

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

Итак, есть ли другие (переносимые) решения, которые позволяют мне генерировать уникальный ключ в контексте мультитенанта?

1 Ответ

0 голосов
/ 20 сентября 2011

Вы неправильно используете аннотацию @Version. Эта аннотация создает числовое поле в качестве поля версии и используется внутри JPA при выполнении блокировок транзакций. Вы не должны писать или даже читать (кроме некоторых ситуаций). Ваша первоначальная идея была правильной: создайте секвенсор, но вам не нужно использовать @Version для этого. Просто имейте класс с атомарным целым числом, которое увеличивается каждый раз, когда вам нужно новое уникальное значение, а затем сохраняется в БД в таблице.

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