【问题标题】:Hibernate: one-to-one mapping is not working correctly休眠:一对一映射无法正常工作
【发布时间】:2015-06-18 12:03:25
【问题描述】:

我在我的 Spring Web 应用程序中使用 Hibernate 框架来处理 Oracle 数据库。

我有这两个具有相互关系的实体:

基本上,每个人可以恰好有零个或一个用户,并且用户必须恰好有一个人。

我想实现一种行为,当我从数据库中选择一些用户时,我会得到映射到它的 Person 实体。

这是我的 POJO:

public class User implements Serializable {

    private String id = null;
    private String username = null;
    private String password = null;
    private boolean enabled = false;
    private Person person = null;
    private LocalDateTime created = null;

    // getters and setters
}

public class Person implements Serializable {

    private String id = null;
    private String firstName = null;
    private String lastName = null;

    // getters and setters
}

这里是对应的配置xml文件:

<hibernate-mapping package="webapp.models">
    <class name="webapp.models.User"
           table="USERS">

        <id name="id"
            type="java.lang.String">
            <column name="ID"
                    not-null="true"
                    unique="true"/>
            <generator class="guid"/>
        </id>

        <property name="username"
                  type="java.lang.String">
            <column name="USERNAME"
                    not-null="false"
                    unique="false"/>
        </property>

        <property name="password"
                  type="java.lang.String">
            <column name="PASSWORD"
                    not-null="false"
                    unique="false"/>
        </property>

        <property name="enabled"
                  type="java.lang.Boolean">
            <column name="ENABLED"
                    not-null="false"
                    unique="false"/>
        </property>

        <property name="created"
                  type="webapp.utils.hibernate.LocalDateTimeUserType">
            <column name="CREATED"
                    not-null="false"
                    unique="false"/>
        </property>

        <one-to-one name="person"
                    class="Person"
                    fetch="select"
                    lazy="false">
        </one-to-one>
    </class>
</hibernate-mapping>

<hibernate-mapping package="webapp.models">
    <class name="webapp.models.Person"
           table="PERSONS">

        <id name="id"
            type="java.lang.String">
            <column name="ID"
                    not-null="true"
                    unique="true"/>
            <generator class="guid"/>    
        </id>

        <property name="firstName"
                  type="java.lang.String">
            <column name="FIRST_NAME"
                    not-null="false"
                    unique="false"/>
        </property>

        <property name="lastName"
                  type="java.lang.String">
            <column name="LAST_NAME"
                    not-null="false"
                    unique="false"/>
        </property>

        <property name="created"
                  type="webapp.utils.hibernate.LocalDateTimeUserType">
            <column name="CREATED"
                    not-null="false"
                    unique="false"/>
        </property>
    </class>
</hibernate-mapping>

我的问题是 user 中的 person 属性始终设置为 null,即使存在相应的 Persons。

这里是执行代码:

public Collection<User> getAll() {
    Session session = null;
    try {
        session = _sessionFactory.openSession();
        Query query = session.createQuery("from User fetch all properties");
        List<User> collection = query.list();
        return Collections.unmodifiableCollection(collection);
    } catch (HibernateException hbEx) {
        return null;
    } finally {
        if (session != null && session.isOpen())
            session.close();
    }
}

我使用 SQL 查询和绑定打开了 Hibernate 日志记录,我发现当它从数据库中选择一个 Person 时,它使用如下查询:

select
    person0_.ID as ID1_0_0_,
    person0_.FIRST_NAME as FIRST_NAME2_0_0_,
    person0_.LAST_NAME as LAST_NAME3_0_0_,
    person0_.CREATED as CREATED4_0_0_ 
from
    PERSONS person0_ 
where
    person0_.ID=?

并且在WHERE 子句中将person0_.ID 设置为用户的ID,因此它不会在用户表中使用PERSON_ID 外键。

我是不是设置有问题或者问题出在哪里?

提前感谢您的帮助。

【问题讨论】:

  • 哪个代码创建了查询?
  • @Jens 添加了执行代码
  • 您的 hbm.xml 文件似乎不正确,请点击此链接-mkyong.com/hibernate/hibernate-one-to-one-relationship-example
  • 我遵循了该教程,但我希望 Person 实体是独立的。在 User 实体中,它只是被 Person 的主键引用。
  • 好的,我刚刚意识到我的 ERD 图不代表一对一的关系,因此我必须重新设计它。

标签: java sql spring hibernate oracle12c


【解决方案1】:

一对一关系必须确保为两个实体分配相同的主键。您应该声明特殊的外部标识符生成器,​​当 constrained=”true” 时,它将从另一个表中获取主键值。

    <id name="id" type="java.lang.Integer">
        <column name="id" />
        <generator class="foreign">
            <param name="property">person</param>
        </generator>
    </id>

【讨论】:

  • 问题是 Person 实体意味着独立于 User 实体。用户只能通过其主键引用 Person 实体。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-07
  • 1970-01-01
  • 2013-05-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多