Как сопоставить ассоциацию «многие ко многим» с классом, сопоставленным с двумя разными таблицами?
-
12-09-2019 - |
Вопрос
У меня есть ваучер-POJO, сопоставленный с двумя таблицами.Первое сопоставление назначает имя сущности «voucherA» и сопоставляет POJO с TableA.Второе сопоставление использует «voucherB» в качестве имени объекта и сопоставляет POJO с TableB.
Теперь у меня также есть клиентский POJO, сопоставленный с TableC.Этот POJO ссылается на ваучеры в списке.
<list name="vouchers" table="TableC_vouchers">
<key column="pid"/>
<list-index column="position" base="0"/>
<!-- how to do that right -->
<many-to-many column="voucher_id" entity-name="voucherB"/>
</list>
Как мне правильно сопоставить список ассоциаций «многие ко многим» от клиентов к ваучерам, чтобы, если POJO клиента сохраняется, объекты ваучера сохранялись в TableB, если они там не существуют, а не в TableA?Можно ли это сделать?Если нет, то как будет выглядеть обходной путь, позволяющий сохранять ваучеры, используемые клиентами, в таблице B?(Таблица A содержит только доступные ваучеры, а не использованные)
Решение
Ваша основная модель кажется неправильной.Твой Voucher
объект предположительно имеет много атрибутов - ВСЕ ли из них изменяются после того, как он используется Customer
?Сомневаюсь.И тем не менее, вы дублируете их в своих таблицах A и B, а это означает, что ваша схема не нормализована.
«Доступный» ваучер и «использованный» ваучер не являются (или не должны быть) одним и тем же объектом.Вместо этого я бы предложил вам создать новую сущность для UsedVoucher
это будет связано с обоими Voucher
как многие к одному и Customer
как многие-к-одному и содержат только «измененные» свойства Voucher
(если есть).Так,
Voucher(id, other attributes) // doesn't change from what you have now
Customer (id, other attributes) // doesn't change except for many-to-many; see below
UsedVoucher(id,
voucher, // what Voucher was used by that customer
customer, // what Customer has used that voucher
changed voucher attributes, // if any
additional attributes // if needed, such as date/time when voucher was used
)
Ваше «многие ко многим» на Customer
станет «один-ко-многим» (набор ваучеров, используемых этим клиентом), ЕСЛИ вам это нужно как обслуживаемая собственность;в противном случае его легко получить с помощью запроса.
Вы не можете физически удалить из Vouchers
Однако в этом сценарии (если только рассматриваемый ваучер никогда не использовался).Вместо этого вам придется выполнить логическое удаление.
Другие советы
Я предлагаю хранить все ваучеры в одной таблице.Чтобы различать используемые и неиспользуемые, вы можете использовать логический флаг или значение дискриминатора (если вы используете наследование в своем Java-коде).
Даже если у вас есть существующие данные, миграция не будет такой уж сложной.Как только все ваучеры окажутся в одной таблице, их отношения с клиентами станут прямыми «многие ко многим».
Я думаю, что поддерживать две таблицы будет сложно.По сути, вы по-прежнему сохраняете сведения о том, используется ли ваучер или нет, но не делаете этого явно.Я уверен, что можно найти обходной путь, но я думаю, что то, что я изложил выше, намного проще.По моему опыту, именно этот путь я выбирал каждый раз, когда сталкивался с подобной проблемой.