2011-02-03 6 views
37

Я работаю над устаревшей базой кода с существующей схемой БД. Существующий код использует SQL и PL/SQL для выполнения запросов в БД. Нам было поручено сделать небольшую часть агрегированной базы данных проекта (вначале все это изменило). Мы решили использовать файлы сопоставления Hibernate 3.3.2.GA и «* .hbm.xml» (в отличие от аннотаций). К сожалению, изменить существующую схему невозможно, потому что мы не можем отменить какие-либо устаревшие функции.Как я могу сопоставить «insert =« false »update =« false »в ключевом свойстве составного идентификатора, который также используется в FK« один ко многим »?

Проблема, с которой я сталкиваюсь, - это когда я пытаюсь сопоставить однонаправленное отношение «один ко многим», где FK равно также часть составного ПК. Вот классы и отображение файлов ...

CompanyEntity.java

public class CompanyEntity { 
    private Integer id; 
    private Set<CompanyNameEntity> names; 
    ... 
} 

CompanyNameEntity.java

public class CompanyNameEntity implements Serializable { 
    private Integer id; 
    private String languageId; 
    private String name; 
    ... 
} 

CompanyNameEntity.hbm.xml

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

<hibernate-mapping package="com.example"> 

    <class name="com.example.CompanyEntity" table="COMPANY"> 
     <id name="id" column="COMPANY_ID"/> 
     <set name="names" table="COMPANY_NAME" cascade="all-delete-orphan" fetch="join" batch-size="1" lazy="false"> 
      <key column="COMPANY_ID"/> 
      <one-to-many entity-name="vendorName"/> 
     </set> 
    </class> 

    <class entity-name="companyName" name="com.example.CompanyNameEntity" table="COMPANY_NAME"> 
     <composite-id> 
      <key-property name="id" column="COMPANY_ID"/> 
      <key-property name="languageId" column="LANGUAGE_ID"/> 
     </composite-id> 
     <property name="name" column="NAME" length="255"/> 
    </class> 

</hibernate-mapping> 

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

update COMPANY_NAME set COMPANY_ID=null where COMPANY_ID=? 

Hibernate пытается Dis-ассоциированными дочерних записей перед обновлением их. Проблема в том, что это поле является частью PK и не является допустимым. Я нашел быстрое решение, чтобы Hibernate не делал этого, чтобы добавить «not-null = 'true» к элементу «key» в родительском сопоставлении. SO может теперь отображение выглядит следующим образом ...

CompanyNameEntity.hbm.xml

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

<hibernate-mapping package="com.example"> 

    <class name="com.example.CompanyEntity" table="COMPANY"> 
     <id name="id" column="COMPANY_ID"/> 
     <set name="names" table="COMPANY_NAME" cascade="all-delete-orphan" fetch="join" batch-size="1" lazy="false"> 
      <key column="COMPANY_ID" not-null="true"/> 
      <one-to-many entity-name="vendorName"/> 
     </set> 
    </class> 

    <class entity-name="companyName" name="com.example.CompanyNameEntity" table="COMPANY_NAME"> 
     <composite-id> 
      <key-property name="id" column="COMPANY_ID"/> 
      <key-property name="languageId" column="LANGUAGE_ID"/> 
     </composite-id> 
     <property name="name" column="NAME" length="255"/> 
    </class> 

</hibernate-mapping> 

Это отображение дает исключение ...

org.hibernate.MappingException: Repeated column in mapping for entity: companyName column: COMPANY_ID (should be mapped with insert="false" update="false") 

Моей проблема сейчас в том, что я судимый к добавьте эти атрибуты в элемент key-property, но это не поддерживается DTD. Я также попытался изменить его на элемент «ключ-много-один», но это тоже не сработало. Итак ...

Как я могу сопоставить «insert =« false »update =« false »на ключевом свойстве составного идентификатора, который также используется в FK« один ко многим »?

+0

После просмотра аннотаций документ Hibernate, это выглядит, как я мог бы быть в состоянии создать желаемое отображение с JPA/Hibernate аннотации. Я буду экспериментировать с этим немного больше и опубликовать свои результаты. –

+0

Отображение, которое я пытаюсь указать, НЕВОЗМОЖНО с использованием файлов * .hbm.xml. Единственный способ добиться этого - использовать аннотации, упомянутые в ответе mcyalcin ниже. –

+1

Я думаю, что это сообщение может решить проблему в конфигурации XML, http://stackoverflow.com/questions/9381029/hibernate-mapping-exception-repeated-column-in-mapping-fority1 –

ответ

77

Я думаю, что аннотация вы ищете:

public class CompanyName implements Serializable { 
//... 
@JoinColumn(name = "COMPANY_ID", referencedColumnName = "COMPANY_ID", insertable = false, updatable = false) 
private Company company; 

И вы должны быть в состоянии использовать подобные сопоставления в hbm.xml, как показано здесь (в 23.4.2):

http://docs.jboss.org/hibernate/core/3.3/reference/en/html/example-mappings.html

+0

Благодарим вас за ответ. В приведенной вами документации документации JBoss она не содержит примеров того, с чем я столкнулся. Я попытался использовать сопоставления точно так же, как они показали, и это все еще не сработало для меня. Похоже, что конкретное сопоставление, которое я пытаюсь выполнить, невозможно с текущей спецификацией DTB HBM. При этом ваше решение с аннотациями не сталкивается с той же проблемой, с которой я столкнулся, поэтому это хорошее решение для всех, у кого есть возможность использовать аннотации. Обычно я рекомендую аннотации всем, у кого есть выбор. –

+0

Интересно. Я использовал пока только аннотации с Hibernate, считая это более удобным, но я думал, что функция аннотации является подмножеством определений сопоставления xml, а не наоборот. Я буду играть с xmls, потому что, если действительно есть недостающая функциональность, следует сообщить об ошибке. Я рад, что ответ помог! – mcyalcin

+1

Но если я хочу вставить и обновить, есть ли другая работа, чтобы выбраться из этого? Потому что я полагаю, insertable = false и updatable = false не позволит мне изменить «компанию». – kinshuk4

0

"Dino TW" предоставил ссылку на комментарий Hibernate Mapping Exception : Repeated column in mapping for entity, который имеет жизненно важную информацию.

Ссылка подсказки для обеспечения «inverse = true» в наборе сопоставлений, я попробовал, и это действительно работает.Это такая редкая ситуация, когда набор Set и Composite объединяется. Сделайте inverse = true, мы оставим вставку & обновление таблицы с помощью составного ключа, который будет позаботиться сам по себе.

Ниже может быть искомое отображение,

<class name="com.example.CompanyEntity" table="COMPANY"> 
    <id name="id" column="COMPANY_ID"/> 
    <set name="names" inverse="true" table="COMPANY_NAME" cascade="all-delete-orphan" fetch="join" batch-size="1" lazy="false"> 
     <key column="COMPANY_ID" not-null="true"/> 
     <one-to-many entity-name="vendorName"/> 
    </set> 
</class> 

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

  • Нет связанных вопросов^_^