如何映射"insert ='false'update ='false'"在也用于一对多FK的复合ID密钥属性上? [英] How can I map "insert='false' update='false'" on a composite-id key-property which is also used in a one-to-many FK?

查看:127
本文介绍了如何映射"insert ='false'update ='false'"在也用于一对多FK的复合ID密钥属性上?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用现有数据库架构在遗留代码库上工作.现有代码使用SQL和PL/SQL在数据库上执行查询.我们的任务是使项目数据库引擎的一小部分不可知(首先是最终更改所有内容).我们选择使用 Hibernate 3.3.2.GA 和"* .hbm.xml"映射文件(与注释相反).不幸的是,更改现有架构是不可行的,因为我们无法退化任何旧版功能.

I am working on a legacy code base with an existing DB schema. The existing code uses SQL and PL/SQL to execute queries on the DB. We have been tasked with making a small part of the project database-engine agnostic (at first, change everything eventually). We have chosen to use Hibernate 3.3.2.GA and "*.hbm.xml" mapping files (as opposed to annotations). Unfortunately, it is not feasible to change the existing schema because we cannot regress any legacy features.

我遇到的问题是当我试图映射单向,一对多关系时,FK也是复合PK的一部分.这是类和映射文件...

The problem I am encountering is when I am trying to map a uni-directional, one-to-many relationship where the FK is also part of a composite PK. Here are the classes and mapping file...

CompanyEntity.java

CompanyEntity.java

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

CompanyNameEntity.java

CompanyNameEntity.java

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

CompanyNameEntity.hbm.xml

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试图做一些愚蠢 ...

This code works just fine for SELECT and INSERT of a Company with names. I encountered a problem when I tried to update and existing record. I received a BatchUpdateException and after looking through the SQL logs I saw Hibernate was trying to do something stupid...

update COMPANY_NAME set COMPANY_ID=null where COMPANY_ID=?

Hibernate尝试在更新子记录之前取消关联它们.问题在于该字段是PK的一部分,不能为空.我发现使Hibernate不执行此操作的快速解决方案是在父映射的"key"元素中添加"not-null ='true'".所以现在映射可能看起来像这样...

Hibernate was trying to dis-associate child records before updating them. The problem is that this field is part of the PK and not-nullable. I found the quick solution to make Hibernate not do this is to add "not-null='true'" to the "key" element in the parent mapping. SO now may mapping looks like this...

CompanyNameEntity.hbm.xml

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>

此映射给出了例外情况...

This mapping gives the exception...

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

我现在的问题是我试图将这些属性添加到key-property元素中,但是DTD不支持.我也尝试过将其更改为多对一"的元素,但这也不起作用.所以...

My problem now is that I have tryed to add these attributes to the key-property element but that is not supported by the DTD. I have also tryed changing it to a key-many-to-one element but that didn't work either. So...

如何将"insert ='false'update ='false'"映射到也用于一对多FK的复合ID密钥属性上?

How can I map "insert='false' update='false'" on a composite-id key-property which is also used in a one-to-many FK?

推荐答案

我认为您要查找的注释是:

I think the annotation you are looking for is:

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

并且您应该能够在hbm.xml中使用类似的映射,如此处所示(在23.4.2中):

And you should be able to use similar mappings in a hbm.xml as shown here (in 23.4.2):

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

这篇关于如何映射"insert ='false'update ='false'"在也用于一对多FK的复合ID密钥属性上?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆