【发布时间】:2012-10-21 06:19:39
【问题描述】:
我正在使用 Hibernate 4。我有这个包含 Category 和 CategoryItem 表的数据库:
CREATE TABLE `test`.`Category` (
`Id` INT NOT NULL AUTO_INCREMENT ,
`Description` VARCHAR(50) NOT NULL ,
PRIMARY KEY (`Id`) )
CREATE TABLE `test`.`CategoryItem` (
`IdCategory` INT NOT NULL ,
`Id` VARCHAR(10) NOT NULL ,
`Description` VARCHAR(100) NOT NULL ,
PRIMARY KEY (`Id`, `IdCategory`) ,
CONSTRAINT `fk_table1_Category1`
FOREIGN KEY (`IdCategory` )
REFERENCES `test`.`Category` (`Id` ))
这用于存储不同的类别或目录及其值。例如:
分类表:
1, 'Genders'
2, 'Marital status'
3, 'Countries'
CategoryItem 表:
1, 'FEM', 'Female'
1, 'MAL', 'Male'
2, 'SIN', 'Single'
2, 'MAR', 'Married'
3, 'US', 'United States'
3, 'UK', 'England'
这些值在整个架构中使用,但仅对 CategoryItem(Id) 进行逻辑引用,例如:
CREATE TABLE `test`.`Person` (
`Id` INT NOT NULL ,
`Name` VARCHAR(30) NULL ,
--this fields are referencing CategoryItem(Id)
`IdGender` VARCHAR(10) NOT NULL ,
`IdMaritalStatus` VARCHAR(10) NOT NULL ,
`IdCountryOrigen` VARCHAR(10) NOT NULL ,
PRIMARY KEY (`Id`) )
是否可以在 Hibernate 中使用一些技术来映射这些表?我现在无法更改此架构。
已编辑:
这些是目前的类和映射:
public class Category implements Serializable {
private int id;
private String description;
private Set<CategoryItem> items = new HashSet<CategoryItem>();
public Category() {
}
//getters and setters omitted
}
public class CategoryItem implements Serializable {
private CategoryItemId id;
private Category category;
private String description;
public CategoryItem() {
}
//getters and setters omitted
}
public class CategoryItemId implements Serializable {
private Category category;
private String id;
public CategoryItemId() {
}
//getters and setters omitted
}
public class Person implements Serializable {
private int id;
private String name;
private CategoryItem gender;
private CategoryItem maritalStatus;
private CategoryItem countryOrigen;
public PersonaNatural() {
}
//getters and setters omitted
}
<class catalog="test" name="test.Category" table="Category">
<id name="id" type="int">
<column name="Id"/>
<generator class="increment"/>
</id>
<property name="description" type="string">
<column length="50" name="Description" not-null="true"/>
</property>
<set inverse="true" name="items">
<key>
<column name="IdCategory" not-null="true"/>
</key>
<one-to-many class="test.CategoryItem"/>
</set>
</class>
<class catalog="test" name="test.CategoryItem" table="CategoryItem">
<composite-id class="test.CategoryItemId" name="id">
<key-many-to-one name="category" class="test.Category">
<column name="IdCategory" not-null="true"/>
</key-many-to-one>
<key-property name="id" type="string">
<column name="Id"/>
</key-property>
</composite-id>
<many-to-one name="category" class="test.Category" fetch="select" insert="false" update="false">
<column name="IdCategory" not-null="true"/>
</many-to-one>
<property name="description" type="string">
<column name="Description" length="100" not-null="true"/>
</property>
</class>
<class catalog="test" name="test.Person" table="Person">
<id name="id" type="int">
<column name="Id"/>
<generator class="increment"/>
</id>
<property name="name" type="string">
<column length="30" name="Name" not-null="false"/>
</property>
<many-to-one name="gender" class="test.CategoryItem" fetch="select">
<column name="IdGender" not-null="true"/>
</many-to-one>
<many-to-one name="maritalStatus" class="test.CategoryItem" fetch="select">
<column name="IdMaritalStatus" not-null="true"/>
</many-to-one>
<many-to-one name="countryOrigen" class="test.CategoryItem" fetch="select">
<column name="IdCountryOrigen" not-null="true"/>
</many-to-one>
</class>
我正在尝试多对一,但我收到此错误:'must have the same number of columns as the referenced primary key'。这是有道理的,因为我假装只在 Person.hbm.xml 上映射 CategoryId(Id)。
我需要指定一个 where 或 discriminator 值来完成左连接条件,因为 CategoryItem(Id) 本身并不是唯一的。
也许这对于 Hibernate 来说甚至是不可能的,但我将不胜感激。 谢谢。
【问题讨论】:
-
如果您想让我们告诉您它们有什么问题,您应该向我们展示您的类及其映射。
-
谢谢@JBNizet,我已经用类和映射文件编辑了我的问题。
-
如果类别项的ID足以唯一标识一个项,那么它应该构成表的主键,以及实体的ID。如果这还不够,那么您应该在 Person 表中有两列来引用性别,另外两列来引用国家,还有另外两列来引用婚姻状况。照原样,您的架构没有多大意义。我强烈建议使用单列代理 ID。
-
我同意@JBNizet 的观点,我只需要对这个模式进行编码,因为这是客户的要求;我将向团队公开在 CategoryItem 表上添加一个新列作为代理 Id 的替代方法。非常感谢您的帮助!
-
正如我所说,如果这个架构有意义,则意味着项目 ID 是唯一的,因此可以用作 Hibernate ID。
标签: hibernate many-to-one discriminator