2015-06-18 3 views
0

Я использую инфраструктуру Hibernate в своем веб-приложении Spring для работы с базой данных Oracle.Hibernate: сопоставление «один к одному» работает некорректно

У меня есть эти 2 сущностей с взаимоотношением: pseudo ERD diagram

В принципе, каждый человек может иметь ровно ноль или один пользователь и пользователь должен иметь ровно один Человек.

Я хочу добиться такого поведения, что, когда я выберу некоторого пользователя из базы данных, я получаю привязанный к нему объект Person.

Вот мой POJOs:

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> 

Моя проблема заключается в том, что людей свойство в пользователе всегда устанавливается в null, хотя соответствующие лица существуют.

Вот код исполнения:

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(); 
    } 
} 

Я включил Hibernate регистрации с запросами SQL и привязками, и я обнаружил, что, когда он выбирает 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 как идентификатор пользователя, поэтому он не принимает внешний ключ PERSON_ID в таблице Users.

Я устанавливаю что-то неправильно или где может быть проблема?

Заранее благодарим за любую помощь.

+0

Какой код создает запрос? – Jens

+0

@Jens Добавлен код исполнения –

+0

Ваш файл hbm.xml не представляется правильным, пожалуйста, перейдите по этой ссылке: http://www.mkyong.com/hibernate/hibernate-one-to-one-relationship-example/ –

ответ

1

Индивидуальные отношения должны гарантировать, что обеим объектам присваивается один и тот же первичный ключ. вы должны объявить специальный генератор внешнего идентификатора, который получит значение первичного ключа из другой таблицы, если constrained = "true".

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

Дело в том, что объект Person должен быть независим от объекта пользователя. Пользователь имеет только ссылку на объект Person своим основным ключом. –

Смежные вопросы