Hibernate一对一映射问题

时间:2011-05-12 05:05:35

标签: xml hibernate

我正在尝试hibernate中的一对一映射,hbm文件和类如下,

Student.hbm.xml:

<hibernate-mapping>
    <class name="com.psl.student.Student" table="STUDENT">
        <meta attribute="class-description">This class contains student details.</meta>
        <id name="studentId" type="long" column="STUDENT_ID">
            <generator class="native" />
        </id>
        <property name="studentName" type="string" length="100"  column="STUDENT_NAME" />
        <one-to-one name="studentAddress" class="com.psl.student.Address" not-null="true" column ="STUDENT_ADDRESS"  />
    </class>
</hibernate-mapping>

Address.hbm.xml:

<hibernate-mapping>
    <class name="com.psl.student.Address" table="ADDRESS">

    <meta attribute="class-description">This class contains the student's address details.</meta>
    <id name="addressId" type="long" column="ADDRESS_ID">
        <generator class="native" />
    </id>

    <property name="street" column="ADDRESS_STREET" type="string" length="250" />
    <property name="city" column="ADDRESS_CITY" type="string" length="50" />
    <property name="state" column="ADDRESS_STATE" type="string" length="50" />
    <property name="zipcode" column="ADDRESS_ZIPCODE" type="string" length="10" />
</class>

</hibernate-mapping>

Student.java:

public class Student implements java.io.Serializable {
private long studentId;
private String studentName;
private Address studentAddress;     

public Student() {
}

public Student(String studentName, Address studentAddress) {
    this.studentName = studentName;
    this.studentAddress = studentAddress;
}

public long getStudentId() {
    return this.studentId;
}

public void setStudentId(long studentId) {
    this.studentId = studentId;
}

public String getStudentName() {
    return this.studentName;
}

public void setStudentName(String studentName) {
    this.studentName = studentName;
}

public Address getStudentAddress() {
    return this.studentAddress;
}

public void setStudentAddress(Address studentAddress) {
    this.studentAddress = studentAddress;
}
}

Address.java:

public class Address implements java.io.Serializable {

private long addressId;
private String street;
private String city;
private String state;
private String zipcode;

public Address() {
}

public Address(String street, String city, String state, String zipcode) {
    this.street = street;
    this.city = city;
    this.state = state;
    this.zipcode = zipcode;
}

public long getAddressId() {
    return this.addressId;
}

public void setAddressId(long addressId) {
    this.addressId = addressId;
}

public String getStreet() {
    return this.street;
}

public void setStreet(String street) {
    this.street = street;
}

public String getCity() {
    return this.city;
}

public void setCity(String city) {
    this.city = city;
}

public String getState() {
    return this.state;
}

public void setState(String state) {
    this.state = state;
}

public String getZipcode() {
    return this.zipcode;
}

public void setZipcode(String zipcode) {
    this.zipcode = zipcode;
}
}

我收到了以下错误:

引起:org.hibernate.InvalidMappingException:无法解析来自资源com / psl / student / Student.hbm.xml的映射文档

引起:org.xml.sax.SAXParseException:必须为元素类型“one-to-one”声明属性“not-null”。

4 个答案:

答案 0 :(得分:7)

您不能同时在两个表上使用一对一和id生成器。

关系数据库中的一对一意味着主键得到同步。在这种情况下:一个人和一个具有相同身份的地址将属于一起。因为学生引用地址,学生主键将作为外键来解决并需要使用地址主键。当使用本机生成器生成自己的id时,这是不可能的。

大多数一对一的关系实际上不应该是一对一的。如果您只想拥有该地址的外键,请将其简单地映射为多对一。

答案 1 :(得分:4)

对于一对一的映射,您必须执行以下操作  

<class name="dto.StudentDto" table="STUDENTDTO">
    <id name="studentId" type="long">
        <column name="STUDENTID" />
        <generator class="assigned" />
    </id>
    <property name="serialVersionUID" type="long" access="field">
        <column name="SERIALVERSIONUID" />
    </property>
    <property name="studentName" type="java.lang.String">
        <column name="STUDENTNAME" />
    </property>
    <many-to-one name="studentAddress" class="dto.Address" not-null="true" cascade="all" unique="true">
        <column name="STUDENTADDRESS" />
    </many-to-one>
</class>

注意:一对一地使用unique =“true”,多对一

答案 2 :(得分:0)

问题是hibernate-mapping-3.0.dtd没有声明一个元素&lt;柱&GT;根据 &LT;一到一个&GT;你只能使用元素&lt;元&GT;或者&lt;式GT; 这里可选的是dtd的一部分 指的是这个。

&LT; ! - 声明两个实体之间的一对一关联(或者来自组件, 组件元素等到实体)。 - &GT;

&LT; !ELEMENT一对一(meta *,formula *)&gt;

&LT; !ATTLIST一对一名称CDATA #REQUIRED&gt;    &LT; !ATTLIST一对一公式CDATA#IMPLIED&gt;    &LT; !ATTLIST一对一访问CDATA#IMPLIED&gt;    &LT; !ATTLIST一对一课程CDATA#IMPLIED&gt;    &LT; !ATTLIST一对一实体名称CDATA#IMPLIED&gt;    &LT; !ATTLIST一对一级联CDATA#IMPLIED&gt;    &LT; !ATTLIST一对一外连接(true | false | auto)#IMPLIE&gt;    &LT; !ATTLIST一对一提取(加入|选择)#IMPLIE&gt;    &LT; !ATTLIST一对一约束(true | false)“false”&gt;    &LT; !ATTLIST一对一外键CDATA#IMPLIED&gt;    &LT; !ATTLIST一对一属性 - 参考CDATA#IMPLIED&gt;    &LT; !ATTLIST一对一懒惰(假|代理|无代理)#IMPLIE&gt;    &LT; !ATTLIST一对一节点CDATA#IMPLIED&gt;    &LT; !ATTLIST一对一embed-xml(true | false)“true”&gt;

并且对于元素一对一,没有名为not-null的属性。

答案 3 :(得分:0)

只需删除not-null="true"映射中的one-to-one