Hibernate Self Присоединиться - PullRequest
       7

Hibernate Self Присоединиться

0 голосов
/ 21 сентября 2009

Фон

У меня есть таблица со столбцами id, imageId, propertyId .

Может быть много изображений, связанных с одним свойством, и может быть много свойств, связанных с одним изображением.

imageId - many-to-many - propertyId

У меня есть список propertyIds, и я хочу узнать все изображения, связанные со всеми propertyIds , используя Hibernate .

Проблема.

Просто сейчас я выбираю по одному свойству за раз и, используя API Критерии, нахожу все imageIds, связанные с этим propertyId, я получаю список imageIds. Я использую этот список imageIds в следующем запросе и говорю

select imageIds where imageId in (imageIds obtained in previous step) where propertyId = x

Таким образом, количество запросов к базе данных будет равно количеству идентификаторов свойств. Я не думаю, что это хорошее решение, так как мне приходилось обращаться к базе данных n раз, я пытался использовать Detached Query, но безуспешно. Есть ли лучшее решение?

Кроме того, когда я наконец получу список imageIds, будет ли хорошей идеей (не будем принимать во внимание количество результатов) сохранять его в сеансе пользователя и разбивать на страницы ИЛИ это хорошая идея повторить весь процесс ИЛИ я должен рассмотреть вопрос о сохранении его в БД для целей нумерации страниц?

Ответы [ 2 ]

2 голосов
/ 22 сентября 2009

Вот проблема с вашей схемой базы данных:

Вы пытаетесь объединить 3 отдельные ассоциации (изображение - коллекция, изображение - свойство, коллекция - свойство) в одну ImageCollection таблицу. Это не хорошая вещь. Хотя вам, вероятно, это удастся с помощью простого SQL (за счет большого количества строк с пустыми столбцами в этой таблице), вы не сможете правильно отобразить это в Hibernate. Кстати, эта таблица не нуждается в суррогатном первичном ключе.

Что вам нужно сделать, так это разделить ее на 3 отдельные таблицы и отобразить модель в «многие ко многим» в Hibernate. Например:

@Entity
public class Image {
  @ManyToMany
  @JoinTable(
    name="IMAGE_PROPERTIES",
    joinColumns=@JoinColumn(name="IMAGE_ID"),
    inverseJoinColumns=@JoinColumn(name="PROPERTY_ID")
  )
  private Collection<Property> properties;

  ...
}
Таблица

IMAGE_PROPERTIES будет содержать только столбцы IMAGE_ID и PROPERTY_ID; у вас также будут таблицы COLLECTION_IMAGES и COLLECTION_PROPERTIES.

После этого вы сможете запрашивать изображения по именам свойств, например:

from Image img
  left join img.properties as prop
  with prop.name in ('Tag1', 'Tag2', 'Tag3')

Если ваши свойства действительно похожи на теги, посмотрите на эту статью для примеров запросов AND / OR / UNION.

Если ваши свойства действительно являются свойствами (то есть они имеют жизненный цикл объекта-владельца и не могут принадлежать сразу нескольким объектам), рассмотрите возможность их разделения на две таблицы (одну для изображений и одну для коллекций) используя связи один ко многим. Таким образом, вам не понадобятся таблицы IMAGE_PROPERTIES и COLLECTION_PROPERTIES сверху.

0 голосов
/ 21 сентября 2009

Итак, у вас есть такой класс (Примечание: я не писал это с ide, поэтому код может быть не синтаксически правильным):

public class Property {
@ManyToMany
private List<Image> images;
}

public class Image {
@ManyToMany
private List<Property> properties;
}

Таким образом, запрос типа select property from Property property должен получить список свойств, к которым вы можете обратиться через обычные свойства Java.

Это то, что вы ищете, или я неправильно понял вопрос?

...