Проблемы с ORMLite и ленивыми коллекциями - PullRequest
5 голосов
/ 30 августа 2011

Я использую ormlite в своем проекте Android.У меня есть два класса

@DatabaseTable(tableName = "usershows")
public class UserShow {
    @DatabaseField(id = true)
    private Integer showId;

    @ForeignCollectionField(eager = false)
    private ForeignCollection<Episode> episodes;
    ...
}

@DatabaseTable(tableName = "episodes")
public class Episode {
    @DatabaseField(id = true)
    private Integer episodeId;

    @DatabaseField(foreign = true)
    private UserShow show;
    ...
}

Я сохраняю свои объекты UserShows, такие как в примере

UserShow show = new UserShow();
userShowDao.create(show);

for (Episode e: eps) {
    e.setShow(show);
    episodeDao.create(e); 
} 

У объекта UserShow есть чужие эпизоды с отложенной коллекцией, но когда япытаюсь получить все пользовательские шоу:

shows = userShowsDao().queryForAll();

Я получаю все объекты шоу с коллекциями эпизодов.Почему это происходит?Коллекция ленива, и я должен получить null или что-то еще, но не коллекцию объекта Episode.Как сделать эту коллекцию действительно ленивой?Было бы здорово, если бы ORMLite имел возможность получать объекты без ленивых коллекций и инициализировать, когда это действительно необходимо.Например, как Hibernate.initialize метод.

Спасибо!

Ответы [ 2 ]

4 голосов
/ 30 августа 2011

Ленивые коллекции были хорошо протестированы и используются многими другими, поэтому, хотя с ними могут быть ошибки, более вероятно, что вас обманывает класс ленивых коллекций.

Когда каждый из UserShow объектов извлекается из DAO, episodes не будет нулевым, а вместо этого будет установлен с экземпляром LazyForeignCollection. Однако дополнительные запросы не будут выполняться, и в коллекции не будет данных Episode. Если вы затем вызовете один из методов в коллекции, например userShow.getEpisodes().iterator(), тогда будет выполнен отдельный запрос, чтобы вы могли выполнить итерации эпизодов этого шоу. Вот как работают ленивые коллекции.

Если вы все еще думаете, что ленивые коллекции не работают, пожалуйста, покажите нам, как вы определяете, что шоу имеют данные эпизодов. Чтобы узнать, какие запросы выполняются и где, вы можете включить вход в Android с помощью ORMLite .


Edit:

Оказывается, @Georgy использовал отладчик для исследования коллекции. Отладчик, скорее всего, вызывает те же самые методы iterator() или toArray(), которые вызывают запросы сбора в этот момент. Таким образом, в коллекции не было никаких эпизодов, пока их не попросил отладчик.

1 голос
/ 30 августа 2011

Ваш пример должен быть в порядке. Я создал соответствующие тестовые таблицы и вставил 2 usershows и 3 episodes. Затем я следил за журналом MySQL (установлен с помощью MySQL с --general-log=<log file name> - см. http://dev.mysql.com/doc/refman/5.5/en/query-log.html).

Полный тест Groovy:

import com.j256.ormlite.dao.DaoManager
import com.j256.ormlite.jdbc.JdbcConnectionSource
cs = new JdbcConnectionSource('jdbc:mysql://localhost/episode?user=root')
epDao = DaoManager.createDao(cs,Episode)
usDao = DaoManager.createDao(cs,UserShow)
usDao.queryForAll().each { println it }

Журнал показывает только один выполненный оператор выбора:

110830 13:11:09     1 Query SELECT * FROM `usershows`

Измените последнюю строку на следующую (которая перебирает все пользовательские шоу и получает поле эпизодов для каждого:

usDao.queryForAll().each { println it.episodes }

Результаты:

110830 13:15:31     1 Query SELECT * FROM `usershows`
                    1 Query SELECT * FROM `episodes` WHERE `show_id` = 1
                    1 Query SELECT * FROM `episodes` WHERE `show_id` = 2
...