Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Hibernate и графы, Загрузка коллекций для графов 
:(
    Опции темы
tikskit
Дата 26.9.2009, 14:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 35
Регистрация: 17.5.2008

Репутация: нет
Всего: нет



Здравствуйте! Мне нужна помощь в написании mapping-файла. Схема данных, с которой я хочу работать с использованием Hibernate, представляет собой графы. Есть объекты Node, имеющие двунаправленные связи друг с другом.
В базе данных объекты хранятся в таких таблицах (Derby):
Код

CREATE TABLE nodes(
    id INTEGER PRIMARY KEY NOT NULL GENERATED ALWAYS AS IDENTITY,
    name VARCHAR(100) UNIQUE
);

CREATE TABLE links (
    node1 INTEGER,
    node2 INTEGER,
    PRIMARY KEY (node1, node2)
); 

Объект Node:
Код

public class Node {
    public int id;
    private String name;
    private Set fellows = new HashSet<Node>();

    public Node() {
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Set getFellows() {
        return fellows;
    }

    public void setFellows(Set fellows) {
        this.fellows = fellows;
    }
}

То есть предполагается, что с объектами Node я буду работать в сессии. И когда вызываю getFellows, подгружаются связанные объекты (т.е. используется отложенная загрузка коллекции).
Проблема в том, что связь в таблице links между парой объектов Node может быть установлена двумя способами. Допустим есть два объекта Node: A и B. Тогда возможно два варианта:


links          
+-------+-------+
| node1 | node2 |
+-------+-------+
| A.id  | B.id  |
+-------+-------+
и
links          
+-------+-------+
| node1 | node2 |
+-------+-------+
| B.id  | A.id  |
+-------+-------+

Оба варианта абсолютно равнозначны, но в базе будет только один из них (любой).
Это значит, что загружая связанные объекты нужно учитывать их оба. Для этого в файле Node.hbm.xml я пытаюсь использовать нативный sql запрос для подгрузки коллекции fellows. Выглядит этот файл у меня так:
Код

<?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="graphstests.Node" table="nodes">
        <id name="id" column="id">
            <generator class="org.hibernate.id.IdentityGenerator"/>
        </id>
        <property name="name" column="name"/>

        <set name="fellows" table="links" lazy="true">
            <key />
            <many-to-many class="graphstests.Node"/>
            <loader query-ref="loadnodes"/>
        </set>
    </class>
    <sql-query name="loadnodes">
        SELECT *
        FROM nodes
        INNER JOIN links ON links.node2=nodes.id
        WHERE links.node1=:id
        UNION
        SELECT *
        FROM nodes
        INNER JOIN links ON links.node1=nodes.id
        WHERE links.node2=:id
    </sql-query>
</hibernate-mapping>


К сожалению это не работает. Я пытаюсь загружать объекты таким образом:
Код

    private static void loadTest() {
        Session s = SessionFactorySource.getInstance().getSession();
        try {
            s.beginTransaction();
            List nodes = s.createQuery("from Node where name like 'Node1'").list();
            Node main = (Node) nodes.get(0);
            Set<Node> fellows = (Set<Node>)main.getFellows();
            for (Node n : fellows) {
                System.out.println("fellow: " + n);
            }
            s.getTransaction().commit();
        } catch (HibernateException e) {
            s.getTransaction().rollback();
            e.printStackTrace();
        }
    }

И когда в цикле пытаюсь пройтись по связанным объектам, получаю ошибку:

Цитата

Exception in thread "main" java.lang.NullPointerException
    at org.hibernate.collection.PersistentSet.iterator(PersistentSet.java:187)
    at graphstests.MainClass.loadTest(MainClass.java:30)
    at graphstests.MainClass.main(MainClass.java:19)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:90)


Как вы считаете, правильно ли я вообще пытаюсь решить задачу, может быть не нужно было использовать loader и нативный запрос для описания отношения «многие ко многим», а нужно было делать как-то по другому? Если loader нормально подходит для этой задачи, то прошу помочь правильно составить и использовать нативный запрос для загрузки коллекции.
Спасибо!

Это сообщение отредактировал(а) powerOn - 26.9.2009, 23:30
PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0587 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.