Problems with ORMLite and lazy collections

邮差的信 提交于 2019-12-06 02:36:32

问题


I am using ormlite in my android project. I have two classes

@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;
    ...
}

I am saving my UserShows objects like in example

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

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

UserShow object have a foreign lazy collection episodes, but when I am trying to get all userShows:

shows = userShowsDao().queryForAll();

I am getting all shows objects with collections of episodes. Why this happens? Collection is lazy and I must to get null or something else but no collection of Episode object. How to make this collection really lazy? It may be cool if ORMLite have ability get objects without lazy collections and initialize when it really need. For example as Hibernate.initialize method.

Thanks!


回答1:


The lazy collections have been well tested and are in use by many others so although there could be bugs with it, it is more likely that you are being tricked by the lazy collection class.

When each of the UserShow objects is retrieved from the DAO, the episodes will not be null but instead will be set with an instance of LazyForeignCollection. However, no additional queries will be made and there will be no Episode data contained by the collection. If you then make a call to one of the methods on the collection such as userShow.getEpisodes().iterator(), then a separate query is made at that time to allow you to iterate through that show's episodes. That's how the lazy collections work.

If you still think that the lazy collections aren't working then please show us how you are determining that the shows have episode data. To see what queries are being done where, you can enable Android logging with ORMLite.


Edit:

It turns out that @Georgy was using the debugger to investigate the collection. The debugger is most likely calling the same iterator() or toArray() methods which cause the collection queries to be issued at that instant. So there weren't any episodes in the collection before the debugger asked for them.




回答2:


Your example should be OK. I created the relevant test tables and inserted 2 usershows and 3 episodes. I then tailed the MySQL log (set by running MySQL with --general-log=<log file name> - see http://dev.mysql.com/doc/refman/5.5/en/query-log.html).

Full test Groovy script:

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 }

Log shows only one select statement ran:

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

Change the last line to the following (which iterates over all usershows and gets the episodes field for each one:

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

Results in:

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


来源:https://stackoverflow.com/questions/7242363/problems-with-ormlite-and-lazy-collections

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!