2015-01-04 3 views
0

Возможно ли иметь однонаправленное отображение «много ко многим» в спящем режиме, чтобы дубликаты «ребенка» не сохранялись? Я использую XML-сопоставление, а не аннотации, потому что это то, с чем я начал.Hibernate многопользовательский однонаправленный без дубликатов

я нашел только эту как потенциальное решение, но я хотел бы знать, если спящий режим может быть сконфигурирован без кодирования: Hibernate cascade many to many creates duplicates in child reference

В моем случае я маршализация XML с JAXB для получения объектов Java, и Мне не нужно двунаправленное отображение.

У меня есть класс (пункт), который имеет набор категорий, а класс категории не ссылается на статью. Что бы я хотел сделать, это сохранить объект статьи и вставлять категории только в таблицу категорий, если они еще не существуют. То, как категории связаны со статьями, - это таблица ссылок.

Причина, по которой я хочу заставить ее работать без кодирования, заключается в том, что я хотел узнать что-то новое (спящий режим). Возможно, у меня неправильное восприятие Hibernate, я подумал, что он может понять, что нужно делать, если я правильно его настрою. До сих пор я провел почти один день обучения в спящем режиме, и он не чувствует себя очень продуктивно, учитывая, что я мог просто создать таблицы db самостоятельно и сделать код для правильной установки/обновления через час.

Вот пример, похожий на мой, где они сохраняют 2 студентов, имеющих одинаковые курсы. Тем не менее, курсы сохраняются только один раз в течение таблице: http://www.dzone.com/tutorials/java/hibernate/hibernate-example/hibernate-mapping-many-to-many-using-annotations-1.html

Вот еще один пример, но он является двунаправленным, и я не могу сделать обратное отображение таким же образом, так как категории не имеют обратную ссылку к статье: http://viralpatel.net/blogs/hibernate-many-to-many-xml-mapping-example/ (Вирусный Patel имеет очень хорошие учебники по пути =)

Article has properties: 
String Title; 
Set<Category> categories; 

Category has property: 
String category; 

в отображении товара (статья) у меня это до сих пор:

<set name="categories" cascade="save-update" table="ItemCategory"> 
    <key column="itemID"/> 
    <many-to-many column="categoryID" class="Category"/> 
</set> 

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

Я в основном хочу использовать Hibernate для того, чтобы просто избегать проектирования таблиц и легко сбрасывать объекты RSS в структурированный формат (например, базу данных nosql).

Обновление: Дубликаты приходит от того, когда другие товары (статьи) добавляются, которые имеют те же категории, которые уже существуют в таблице категории. . первый Предмет имеет категории Экономика и политика Вторая статья имеет экономию

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

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

Обновление 2: Я изменил класс Item на набор строк вместо категорий. отображения теперь выглядит следующим образом:

<set name="categories" table="Category"> 
    <key column="itemID"/> 
    <element column="category" type="string"/> 
</set> 

Это удаляет соединяющую таблицу I нужную для избежания дублирования данных. Теперь категории или теги отображаются в таблице категорий столько раз, сколько они произошли во всех элементах (статьях).

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

Update 3: Моя проблема кажется похожа на это: Using saveOrUpdate() in Hibernate creates new records instead of updating existing ones

Update 4: я перешел обратно к тому, набор категорий в классе Item, чтобы проверить, если он работает с категорией Category.category. Отображение для элемента:

<set name="categories" cascade="save-update" table="ItemCategory"> 
    <key column="itemID"/> 
    <many-to-many column="category" class="Category"/> 
</set>  

Отображение для Категория:

<id column="category" name="category" unsaved-value="0"> 
    <generator class="assigned"/> 
</id> 

В результате я получаю исключение: org.hibernate.NonUniqueObjectException: другой объект с тем же значением идентификатора уже связанные с сеансом

ответ

0

Так что, если ваша категория имеет только один атрибут, вы можете сделать это:

@Id private String category; 

Вы также можете иметь в JPA

@ElementCollection private Set<String> categories; 

Для дубликата ребенка в вашем наборе:

В Java, в "Set" не может иметь дубликат.

  • Вы можете переопределить equals/hashcode вашего объекта Category. Но будьте осторожны, вы должны проверить спецификацию JPA перед переопределением.

  • Вы можете найти категорию с помощью «выбрать» и попытаться ее добавить. Элемент категории будет находиться в вашем контексте персистентности, поэтому он будет иметь тот же указатель в вашем «Set». Создайте новую категорию, если она не найдена.

+0

Я не мог найти элемент-коллекцию в отображении XML, и я нашел это: http://stackoverflow.com/questions/25720369/elementcollection-using-xml-configuration Я сделал это с помощью набора, и в классе Item я уменьшил набор категорий как набор строк. Это ИМХО, только избегая проблемы. Я хотел бы узнать для справки в будущем, если можно использовать таблицу соединений таким образом, чтобы я не повторял категории в таблице категорий. То есть только вставить, если категория не существует. – user979899

+0

Вы не можете копировать, если ваш идентификатор является вашей категорией. И ElementCollection - JPA. Я думаю, у вас есть что-то подобное с спящим режимом. –