Проблема с отображением Spring-hibernate
-
22-09-2019 - |
Вопрос
У меня есть приложение spring-hibernate, которое не может правильно отобразить объект:в принципе, у меня есть 2 объекта домена, a Post
и еще User
.Семантика такова, что каждому Сообщению соответствует 1 Пользователь.
Тот самый Post
доменный объект выглядит примерно следующим образом:
class Post {
private int pId;
private String attribute;
...
private User user;
//getters and setters here
}
Как вы можете видеть, Post
содержит ссылку на User
.Когда я загружаю Post
объект, я хочу, чтобы соответствующий User
объект, который будет загружен (лениво - только тогда, когда это необходимо).
Мое отображение выглядит следующим образом:
<class name="com...Post" table="post">
<id name="pId" column="PostId" />
<property name="attribute" column="Attribute" type="java.lang.String" />
<one-to-one name="User" fetch="join"
class="com...User"></one-to-one>
</class>
И, конечно, у меня есть базовое отображение для User
настроено.
Что касается моей схемы таблицы, то у меня есть таблица под названием post
с иностранным UserId
который ссылается на user
таблица.
Я думал, что эта настройка должна сработать, НО когда я загружаю страницу, которая вызывает отложенную загрузку User
объект, я замечаю, что генерируется следующий запрос Hiberate:
Select ... from post this_ left outer join user user2_ on this.PostId=user2_.UserId ...
Очевидно, что это неправильно:это должно быть соединение UserId
От post
с UserId
От user
, но вместо этого его неправильное присоединение PostId
От post
(его первичный ключ) с UserId
От user
.
Есть какие-нибудь идеи?Спасибо!
Обновить:Благодаря паре постов ниже я теперь понимаю, что мне следовало использовать сопоставление "многие к одному" вместо "один к одному".Я изменил отображение в разделе post
к следующему:
<many-to-one name="User" class="com...User" column="uId"/>
Но теперь я получаю сообщение об ошибке во время выполнения, сообщающее мне, что атрибут не вызывается uId
.Это имеет смысл, поскольку у меня нет uId
колонка в моем post
доменный объект (у меня просто есть ссылка на user
объект).Теперь я действительно сбит с толку относительно того, как я могу заставить Hibernate работать, чтобы понять, что ему нужно сопоставить внешний ключ из таблицы post в таблицу user.Следует явно добавить uId
приписывать моему post
доменный объект, который должен быть плейсхолдер для внешнего ключа?
Я надеюсь, что в моих словах есть смысл...
Решение
Поскольку у пользователя много сообщений, ваша ассоциация на самом деле является "многие к одному", а не "один к одному".Это должно сработать, если вы соответствующим образом сопоставите его.
Редактировать:Да, вы можете сопоставить свойство Post.user в публикации с "многие к одному" или задать User.posts в User с "один ко многим", или и то, и другое.Указали ли вы имя вашего столбца внешнего ключа?
Редактировать 2:В режиме гибернации "столбец" в базе данных сопоставляется "свойству" в вашем Java-классе.То есть атрибут column содержит имя вашего столбца внешнего ключа в базе данных, а не имя какого-либо свойства в вашем классе Java.Если я правильно понял ваш вопрос, вы должны использовать "userId", а не "uId".
О, и fetch="join" не может быть ленивым, так как он требует, чтобы пользователь выбирался в том же запросе, что и post.
Другие советы
Это поведение взаимно однозначного сопоставления.Обычно они используют общий первичный ключ.Hibernate предполагает, что первичный ключ post совпадает с первичным ключом user. Эта страница обобщает это поведение.
Я подозреваю, что на самом деле у одного пользователя может быть более одного сообщения.Это делает ваше сопоставление "один ко многим".