Hibernate не загружает связанный объект - PullRequest
3 голосов
/ 05 января 2011

Я пытаюсь загрузить спящий объект ForumMessage, но в нем содержится другой объект Users, а объект Users не загружается.

Файл сопоставления моего ForumMessage:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated Jan 4, 2011 10:10:29 AM by Hibernate Tools 3.4.0.Beta1 -->
<hibernate-mapping>
    <class name="com.BiddingSystem.Models.ForumMessage" table="FORUMMESSAGE">
        <id name="ForumMessageId" type="long">
            <column name="FORUMMESSAGEID" />
            <generator class="native" />
        </id>
        <property name="ForumMessage" type="java.lang.String">
            <column name="FORUMMESSAGE" />
        </property>
        <many-to-one name="User" class="com.BiddingSystem.Models.Users" fetch="join">
            <column name="UserId" />
        </many-to-one>
        <property name="DatePosted" type="java.util.Date">
            <column name="DATEPOSTED" />
        </property>
        <many-to-one name="Topic" class="com.BiddingSystem.Models.ForumTopic" fetch="join">
            <column name="TopicId" /> 
        </many-to-one>
    </class>
</hibernate-mapping>

и яЯ использую следующий код:

Session session = gileadHibernateUtil.getSessionFactory().openSession();

            SQL="from ForumMessage";


    System.out.println(SQL);
    Query query=session.createQuery(SQL);
    System.out.println(query.list().size());
    return new LinkedList <ForumMessage>(query.list());

Ответы [ 2 ]

3 голосов
/ 05 января 2011
<many-to-one name="User" class="com.BiddingSystem.Models.Users" fetch="join" lazy="false">

Вам также необходимо добавить lazy = "false".

2 голосов
/ 06 января 2011

Вы можете добавить lazy="false" к сопоставлению «многие к одному», которое будет загружать пользователей при загрузке ForumMessage.В качестве альтернативы вы можете инициализировать список пользователей, используя Hibernate.initialize ().Просто убедитесь, что вы делаете это, прежде чем закрыть сеанс.

Session session = gileadHibernateUtil.getSessionFactory().openSession();
string sql = "from ForumMessage";
Query query = session.createQuery(sql);
List results = query.list()
for(ForumMessage message : results)
{
    Hibernate.initialize(message.User);
}
return new LinkedList <ForumMessage>(results);

Вы должны сделать только один из них, если вам это нужно.Hibernate по умолчанию ленивый загружает объекты, чтобы избежать ненужных вызовов в базу данных.Например:

public LinkedList getMessages()
{
    //It's assumed the session is opened and closed elsewhere.
    string sql = "from ForumMessage";
    Query query = session.createQuery(sql);
    List results = query.list();
    //The overhead of extra calls to the database occur here.
    //This would have a similar impact if lazy load is set to false.
    for(ForumMessage message : results)
    {
        Hibernate.initialize(message.User);
    }
    return new LinkedList <ForumMessage>(results);
}

public void printMessages()
{
    LinkedList messages = getMessages();
    for(ForumMessage message : messages)
    {
        System.out.println(message.ForumMessage);
    }
}

В приведенном выше примере кода возникают накладные расходы на загрузку всех объектов Users, но эти объекты никогда не используются.Если бы использовалась ленивая загрузка Hibernate, то эти дополнительные издержки не возникли бы.В следующем примере список пользователей не загружается, пока этот список не используется.Таким образом, вызовы в базу данных не выполняются до тех пор, пока данные действительно не потребуются.

public LinkedList getMessages()
{
    //It's assumed the session is opened and closed elsewhere.
    string sql = "from ForumMessage";
    Query query = session.createQuery(sql);
    List results = query.list();
    return new LinkedList <ForumMessage>(results);
}

public void printMessages()
{
    LinkedList messages = getMessages();
    for(ForumMessage message : messages)
    {
        //Hibernate will load the users objects here when they are accessed.
        for(Users user : message.User)
        {
            System.out.println(user);
        }
    }
}

Следует обратить внимание на один момент, когда ленивая загрузка - это вся загрузка, которая должна выполняться в активном сеансе.Если у вас нет активного сеанса и вы пытаетесь получить доступ к чему-то, что еще не было загружено, Hibernate выдаст LazyInitializationException.

Кроме того, использование функции отложенной загрузки Hibernate больше соответствует идее невежества постоянства, тогда как использование Hibernate.initialize () - нет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...