Как сопоставить "insert=' false 'update= 'false' "с ключом-свойством composite-id, которое также используется в FK "один ко многим"?

Я работаю над базой устаревшего кода с существующей схемой БД. Существующий код использует SQL и PL/SQL для выполнения запросов к БД. Нам было поручено сделать небольшую часть проекта database-engine agnostic (сначала изменить все в конечном итоге). Мы решили использовать спящий режим 3.3.2.Га и"*.hbm.xml" файлы сопоставления (в отличие от аннотаций). К сожалению, невозможно изменить существующую схему, потому что мы не можем регрессировать любое наследие особенности.

проблема, с которой я сталкиваюсь, заключается в том, что я пытаюсь отобразить однонаправленное отношение "один ко многим", где 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>

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

update COMPANY_NAME set COMPANY_ID=null where COMPANY_ID=?

Hibernate пытался отключить дочерние записи перед их обновлением. Проблема в том, что это поле является частью PK и не-nullable. Я нашел быстрое решение, чтобы сделать Hibernate не делать этого, чтобы добавить "not-null='true'" к элементу "key" в Родительском сопоставлении. Так что теперь может mapping выглядеть так...

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' " с ключом-свойством composite-id, которое также используется в один-ко-многим ФК?

2 ответов


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

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


"Dino TW" предоставил ссылку на комментарий исключение отображения Hibernate: повторяющийся столбец в сопоставлении для сущности, который имеет жизненно важную информацию.

ссылка намекает на предоставление "inverse=true" в отображении набора, я попробовал, и это действительно работает. Это такая редкая ситуация, когда набор и составной ключ объединяются. Make 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>