Весна-спящий картографическая проблема - PullRequest
2 голосов
/ 25 марта 2010

У меня есть приложение Spring-Hibernate, которое не может правильно отобразить объект: в основном у меня есть 2 объекта домена, 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. Это имеет смысл, поскольку в моем доменном объекте post нет столбца uId (у меня просто есть ссылка на объект user). Теперь я действительно запутался в том, как заставить Hibernate понять, что ему нужно сопоставить внешний ключ из таблицы записей в таблицу пользователей. Должен ли явно добавляться атрибут uId к моему post объекту домена, чтобы он был заполнителем для внешнего ключа?

Надеюсь, у меня есть смысл ...

Ответы [ 2 ]

1 голос
/ 25 марта 2010

Так как у пользователя много постов, ваша ассоциация на самом деле "один-к-одному", а не "один-к-одному". Это должно работать, если вы отобразите его соответствующим образом.

Редактировать : Да, вы можете сопоставить свойство Post.user в Post с «много-к-одному» или установить User.posts в User с «один-ко-многим» ", или оба. Вы указали название своего столбца внешнего ключа?

Edit2 : В Hibernate, «столбец» в базе данных сопоставляется с «свойством» в вашем Java-классе. То есть атрибут column содержит имя столбца внешнего ключа в базе данных, а не имя какого-либо свойства в вашем классе Java. Если я правильно понял ваш вопрос, вы должны использовать «UserId», а не «uId».

Да, и fetch = "join" не может быть ленивым, поскольку он требует, чтобы пользователь выбирался в том же запросе, что и сообщение.

0 голосов
/ 25 марта 2010

Это поведение однозначного сопоставления. Они обычно имеют первичный ключ. Hibernate предполагает, что первичный ключ post совпадает с первичным ключом пользователя. Эта страница обобщает это поведение.

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

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