Hibernate一对一映射不会在MySQLWorkbench上生成一对一的映射?

时间:2017-06-10 17:47:32

标签: java xml hibernate hibernate-mapping

我正在学习Hibernate课程。我有以下实体类:

用户

package com.example.model;

import java.util.ArrayList;
import java.util.List;

import lombok.Data;

@Data
public class User
{
    private int id;
    private String name;
    private ProteinData proteinData;
    private List<UserHistory> history = new ArrayList<UserHistory>();

    public User() {
        setProteinData(new ProteinData());
    }

    public void setProteinData(ProteinData proteinData) {
        this.proteinData = proteinData;
        proteinData.setUser(this);
    }

    public void addHistory(UserHistory historyItem) {
        historyItem.setUser(this);
        history.add(historyItem);
    }
}

ProteinData

package com.example.model;

import lombok.Data;

@Data
public class ProteinData
{
    private int id;
    private User user;
    private int total;
    private int goal;
}

使用XML完成映射,如下所示:

User.hbm.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
                                   "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.example.model.User" table="USER">
        <id name="id" type="int" column="ID">
            <generator class="identity" />
        </id>
        <property name="name" type="string" column="NAME" />
        <one-to-one name="proteinData" class="com.example.model.ProteinData" cascade="save-update" />
        <list name="history" table="USER_HISTORY" inverse="true" cascade="save-update">
            <key column="USER_ID" />
            <list-index column="POSITION" />
            <one-to-many class="com.example.model.UserHistory" />
        </list>
    </class>
</hibernate-mapping>

ProteinData.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
                                   "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.ugultopu.model.ProteinData" table="PROTEINDATA">
        <id name="id" type="int">
            <column name="ID" />
            <generator class="foreign">
                <param name="property">user</param>
            </generator>
        </id>
        <one-to-one name="user" class="com.ugultopu.model.User" constrained="true" />
        <property name="total" type="int">
            <column name="TOTAL" />
        </property>
        <property name="goal" type="int">
            <column name="GOAL" />
        </property>
    </class>
</hibernate-mapping>

当我运行应用程序时,它可以正常工作。但是,即使将UserProteinData之间的关系指定为一对一,当我使用Hibernate生成的模式在MySQLWorkbench上生成模型图时,User之间的关系也是如此。并且ProteinData被描述为一对多:

Model diagram on MySQLWorkbench

这可能是什么原因?

更新

这是按照Naros的答案中所指定的进行以下更改后的模型图:

<!-- User.hbm.xml -->
<one-to-one name="proteinData" property-ref="user" ... />

<!-- ProteinData.hbm.xml -->
<many-to-one name="user" unique="true" not-null=true" ... />

Model diagram on MySQLWorkbench after making the changes specified in Naros' answer

1 个答案:

答案 0 :(得分:0)

很可能是因为UserProteinData表中没有为两个实体之间的关系定义唯一约束,因此MySQLWorkbench认为它是一对多的。

一种方法是在HBM映射中手动指定唯一约束:

<hibernate-mapping>
  ...
  <database-object>
    <create>ALTER TABLE t ADD CONSTRAINT c UNIQUE (..)</create>
    <drop>ALTER TABLE t DROP CONSTRAINT c</drop>
  </database-object>
</hibernate-mapping>

如果使用JPA orm.xml

,另一种方法是在表级添加唯一约束
<entity class="User">
  <table>
    <unique-constraint>
      <column-name>proteinData_id</column-name>
    </unique-constraint>
  </table>
  ...
</entity>
<entity class="ProteinData">
  <table>
    <unique-constraint>
      <column-name>user_id</column-name>
    </unique-constraint>
  </table>
  ...
</entity>  

或者将其指定为带注释的类的一部分。