2012-05-07 3 views
0

У меня есть соединение OneToMany между таблицами Результат и ResultAux. Я могу получить набор ResultAux Объекты с Результат. После этого я добавляю несколько объектов ResultAux, чтобы установить и использовать merge для каждой записи набора для сброса изменений в базу данных. Как это:Спящий режим: новая или старая запись

Set<ResultAux> resultAuxes = result.getResultAuxes(); 
if (resultAuxes != null) { 
    for (ResultAux resultAux : resultAuxes) { 
     resultAux = getDaoFactory().getResultAuxDAO().merge(resultAux); 
    } 
} 

Для некоторых дополнительных действий, мне нужно знать, установить запись в новую запись и будет вставлена ​​в таблицу, или это старый и (модифицированный или нет) будет обновляться. Я заметил, что все записи ResultAux уже имеют идентификатор, поэтому я не могу проверить его на null как я сделал для других таблиц. Есть ли способ определить такую ​​вещь (возможно, не включать дополнительные библиотеки)?

EDIT:

<hibernate-mapping> 
    <class name="ResultAux" table="RESULT_AUX"> 
     <id name="id" column="ID"> 
      <generator class="native" /> 
     </id> 

     <property name="additinalInfoType" column="AITYPE" type="dao.hibernate.utl.AdditinalInfoEnumType" /> 
     <property name="sorter" column="SORTER" /> 
     <property name="value1" column="VAL1" /> 
     <property name="value2" column="VAL2" /> 

     <many-to-one name="result" column="RESULT_ID" class="Result" /> 
    </class> 
</hibernate-mapping> 

<hibernate-mapping> 
    <class name="Result" table="RESULT"> 
     <id name="id" column="ID"> 
      <generator class="native" /> 
     </id> 

     <property name="questionNumber" column="Q_NUM" /> 
     <property name="answerNumber" column="A_NUM" /> 
     <property name="questionGroup" column="Q_GRP" /> 
     <property name="answerValue" column="A_VAL" /> 
     <set name="resultAuxes" inverse="true" cascade="all-delete-orphan" 
      lazy="false"> 
      <key column="RESULT_ID" /> 
      <one-to-many class="ResultAux" /> 
     </set> 
    </class> 
</hibernate-mapping> 
+0

Я бы сказал, что объект, не имеющий постоянного доступа, не имеет идентификатора. Вы уверены, что у каждой записи набора есть идентификатор? – sp00m

+1

Я думаю, вы не должны использовать слияние в resultAux, но в классе результатов, hibernate должен обрабатывать одно для многих отношений. Не могли бы вы также разместить свою конфигурацию отображения? –

+0

@ sp00m: Hibernate не моя сильная сторона. У меня есть некоторые сомнения в том, что происходит, когда я добавляю запись в набор ResultAux, полученный из объекта Result. Кроме того, набор результатов Result's сохраняется выше заданного кода. Возможно, это каскадирование, что делает ResultAux'es постоянным в точке выполнения этого кода. –

ответ

0

Использование native в качестве первичного ключа стратегии генерации вызывает спящий режим, чтобы выбрать identity, sequence или hilo в качестве стратегии поколения ПК в зависимости от возможностей базовой БД.

Я думаю, что для вашей БД, спящий режим выбирает «последовательность» стратегию таким образом, что вы можете столкнуться с этой проблемой (записей, которые не вставленные в БД может иметь назначенный идентификатор) с помощью следующих кодов:

Set<ResultAux> resultAuxes = result.getResultAuxes(); 
ResultAux newResultAux = new ResultAux(); 

/** 
* As session.save() requires to return the ID for the saved instance , if "sequence" strategy is 
* used , Hibernate will hit the DB to select the next ID (eg. select some_seq.NEXTVAL) to be used 
* for the saved instance. So newResultAux will have an ID after save() but actually it is not saved to 
* the DB yet as saving to the DB occurs during session.flush() 
*/ 
session.save(newResultAux); 
resultAuxes.add(newResultAux); 

Одним из решений является добавление свойства @Version к ResultAux. Затем вы можете проверить значение этого свойства @Version, чтобы определить, является ли это новой записью или нет, поскольку свойство @Version для новой записи должно быть NULL

+0

На самом деле ... Я включил SQL-журнал в спящий режим. И сгенерированные SQL-операторы для новых записей - это вставки с нулевым именем. Поэтому вставка должна происходить перед рассматриваемым кодом. Как вы думаете? –

+0

Если INSERT SQL с идентификатором null, то эти записи уже вставлены и, конечно, у них есть идентификаторы. Итак, что вы хотите определить на самом деле? Определите только что вставленные записи или определите записи, которые будут вставлены в таблицу? –

+0

Я попытался прокомментировать код, сохраняющий ResultAux-es. Он работает независимо от этого.Так что я был прав, это каскадно. Как я сказал sp00m Hibernate не моя сильная сторона. Вопрос не работает. Благодаря! –

0

Я не уверен, что мой ответ будет решить вашу проблему, но вернуться на @EugenioCuevas комментарий, я бы сделал что-то вроде этого, чтобы сохраняться ваши дочерние объекты:

Set<ResultAux> resultAuxes = result.getResultAuxes(); 
if (resultAuxes != null) { 
    for (ResultAux resultAux : resultAuxes) { 
     resultAux.setResult(result); 
    } 
} 
getDaoFactory().getResultDAO().merge(result); 

Hibernate должен тогда самостоятельно управлять своими отношениями.

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