2010-02-04 5 views
0

У меня есть класс пользователя hibernate, класс Clerk и класс Consumer. Все эти карты соответствуют их собственным таблицам в базе данных. Пользователь ПК также действует как ПК Клерка и Потребителя.Таблица Hibernate -using для каждого подкласса - как связать существующий объект суперкласса с объектом подкласса

Итак, теперь проблема заключается в том, что если пользователь изначально является Клерком, у него есть запись в таблице «Пользователи» и «Клерки». Если этот пользователь хочет стать потребителем, я хочу связать запись этого пользователя с записью нового потребителя. Поэтому, даже если я передаю userId записи пользователя, он рассматривает его как нового пользователя для сохранения и дает исключение duplicate_key. Как сообщить Hibernate связать один и тот же пользовательский объект с этим новым объектом Consumer?

+0

Есть ли причина, почему люди настаивают на совместном использовании первичных ключей? Что случилось с уникальным Первичным ключом для каждой таблицы и с столбцом внешнего ключа, ссылающимся на родительскую таблицу? –

+0

@McWafflestix: Я использовал второй подход в прошлом и глубоко сожалел об этом. Это делает беспорядок из индексации и производительности в целом и невероятно подвержен ошибкам. Вы почувствуете то же самое при первом выполнении необратимой операции и через несколько секунд поймете, что вместо «производного» ключа вы использовали «базовый» ключ. – Aaronaught

ответ

0

Нет, вы не можете. Вы пытаетесь реализовать множественное наследование. Пользователь не может быть как клерком, так и потребителем на языке, который не поддерживает множественное наследование. Если это допустимый сценарий, вам следует сопоставить использование композиции, а не наследования, чтобы ваш пользовательский класс имел дочерние объекты Clerk и Consumer, либо оба, либо оба из которых могут быть нулевыми.

+0

Спасибо за ответ .. Я думал то же самое. Что касается ПК, мне даже не понравилась концепция совместного использования ПК, но была построена в системе и приложила бы немало усилий для изменения схемы и кода .. То же самое верно для изменения наследования теперь в композиции. Так же верно, что объект суперкласса может быть только одного типа объекта подкласса. В нашем случае, если клерк хочет стать потребителем системы, то он не может быть сопоставлен с одним и тем же пользователем? Спасибо за вашу помощь .. – Chins

+0

Он не может быть и клерком, и потребителем. Вы можете изменить базу данных, чтобы превратить его из клерка в потребителя, но я не думаю, что есть способ сделать это через NHibernate. –

0

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

0

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

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

Рассмотрим эту модель вместо:

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

В коде это будет выглядеть примерно так: класс Пользователь { Карта, роль> роли;

<T extends Role> T as(<Class<T>> roleClass>){ 
    return (T) roles.get(roleClass); 
} 

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

Смежные вопросы