我正在处理一个遗留代码库,其中存在一个现有的数据库模式。现有代码使用SQL和PL/SQL在数据库上执行查询。我们被要求使项目的一小部分与数据库引擎无关(首先更改所有内容)。我们选择使用Hibernate 3.3.2.GA和“*.hbm.xml”映射文件(而不是注释)。不幸的是,由于不能回退任何遗留功能,因此无法更改现有模式。
我遇到的问题是,当我尝试映射单向一对多关系并且FK也是复合PK的一部分时。以下是相关类和映射文件...
CompanyEntity.java
我遇到的问题是,当我尝试映射单向一对多关系并且FK也是复合PK的一部分时。以下是相关类和映射文件...
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在更新子记录之前尝试取消关联它们。问题在于此字段是PK的一部分,而且不能为空。我找到了一个快速解决方案,让Hibernate不这样做是在父映射中添加"not-null='true'"到"key"元素。因此,现在我的映射看起来像这样...
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支持。我还尝试将其更改为key-many-to-one元素,但也没有起作用。那么...
如何将“insert ='false' update ='false'”映射到一个组合ID key-property,该属性还用于一个一对多的外键?