2015-02-19 2 views
3

У меня есть 2 Java-класса, один из которых называется Definition, и один из них - Classification. Определение имеет список классификаций, поэтому 0..n мощность.Удалить взаимосвязь между объектами с помощью HQL

Вот что мое объектно-реляционное отображение выглядит следующим образом:

<?xml version="1.0"?> 
<!DOCTYPE hibernate-mapping PUBLIC 
     "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 
     "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 

<hibernate-mapping> 
    <class name="com.myPackage.Definition" table="definition"> 
     <id name="id" column="ID" type="java.lang.Long"> 
      <generator class="increment" /> 
     </id>   

     <!-- definition will have many to many asscoiations with Classes -->  
     <set name="classes" table="class_definition" cascade="save-update"> 
      <key column="definition_id" />   
      <many-to-many column="class_id" class="com.myPackage.Classification" foreign-key="fk_class_definition" /> 
     </set> 

    </class> 
</hibernate-mapping> 

То, что я пытаюсь сделать теперь удалить связь между определением и классификацией. Например, определение X имеет классификацию A, B и C, и я хочу удалить ссылку на классификацию C.

Я знаю, как написать запрос на удаление в HQL для удаления объекта класса. Но я не знаю, как удалить значение атрибута моего класса.

Может ли кто-нибудь посоветовать?

+0

Вы сказали, что это отношение 0..n, что означает '@ OneToMany', но у вас есть« много-ко-многим »в файле сопоставления, какой из них правильный? Это двунаправленная или однонаправленная связь? –

+0

Я тоже думал, но это может быть просто странное сопоставление спящего режима? – claudio495h

+0

Нет, не спящий сбой, правильное отображение - '' – claudio495h

ответ

0

Я думаю, что это можно сделать, используя update запрос, а не delete, потому что вы обновляете классификацию, а не удаляете ее. Попробуйте что-то вроде этого

update Classification c set c.definition = null where c.definition.id = :defId 

EDIT

Это при условии, что соотношение между Definition и Classification является двунаправленным @OneToMany, как вы сказали в своем вопросе, а не many-to-many, как говорит ваш файл отображения.

+0

Я думаю, что его сопоставление с таблицей соединений, так что это не сработает, исправьте меня, если я ошибаюсь. – claudio495h

+0

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

+0

@PredragMaric Да, это двунаправлено, извините за мой последний ответ – Hazaart

0

Вы можете прочитать определение x из базы данных, выполнить обычный процесс удаления для классификации и снова сохранить x. Это должно сделать это.

+0

Спасибо, но мое требование - использовать только HQL, не изменяя объект в слое JAVA. – Hazaart

0

Я думаю, вы могли бы использовать опцию orphanRemoval=true, так что вы бы только удалить экземпляр Classiciation из списка classiciations в экземпляре Definition

Обратите внимание, что эта опция доступна только для 1: п (ака OneToMany) и 1: 1 (ака OneToOne) отношений, см here

EDIT:

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


Definition x = fetchSomeDefinitionFromTheDatabase(); 
Classification c = x.getClassifications().get(0); 
x.getClassifications().remove(c); 
definitionDaoOrService.update(x); 

Поскольку вы выбрали save-update как каскадный тип, ассоциация между x и c должны исчезнуть, но оба они до сих пор существуют.

+0

orphanRemoval удалит Clasification, когда вы устраните его из определения, вероятно, вызывая исключение, если одна и та же классификация используется в другом определении (ссылочная целостность), и это может быть не то, что предназначалось OP. – claudio495h

+0

orphanRemoval возможно только в отношениях 1: n или 1: 1 https://docs.oracle.com/cd/E19798-01/821-1841/giqxy/, поэтому описанный вами сценарий не может произойти – wastl

+0

Я стою исправлено. – claudio495h

2

Из вышеприведенного вопроса я вижу проблему в моделировании данных решения. В соответствии с приведенной выше конструкцией Объект определения может содержать несколько объектов классификации. И поскольку между этими двумя объектами существует взаимосвязь «многие-ко-многим», один объект классификации может ассоциироваться с несколькими объектами определения.

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

Текущая модель: enter image description here

Предлагаемая модель: enter image description here

Согласно предложенной модели, то не требуется, чтобы обновить любой атрибут из системы правовой записи классификации объектов. Вместо этого ваша работа будет больше об удалении &, создавая новые объекты ClassificationMapper. Класс образца для классификации будет выглядеть, как показано ниже:


class ClassificationMapper{ 
    Long definitionId; // Primary key for Definition 
    Long classificationId; // Primary key for Classification 
} 

ClassificationMapper класс будет иметь много-к-1 композиционные отношения с классом Определения и многой-к-1 ассоциативной связью с классом классификации.

+0

Изменение самого приложения не является для меня вариантом. Глядя на ответы, которые я получил до сих пор, кажется, что это невозможно сделать так, как я имел в виду. Я вознаграждаю вас за щедрость, потому что это лучшее решение, которое было предложено. – Hazaart

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