Problems with ORMLite and lazy collections

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 save UserShows objects like in the example

 UserShow show = new UserShow(); userShowDao.create(show); for (Episode e: eps) { e.setShow(show); episodeDao.create(e); } 

The UserShow object has episodes of other people's lazy collections, but when I try to get all userShow:

 shows = userShowsDao().queryForAll(); 

I get all show objects with collections of episodes. Why is this happening? The collection is lazy and I have to get zero or something else, but there is no collection of an Episode object. How to make this collection really lazy? This can be great if ORMLite has the ability to retrieve objects without lazy collections and initialize when it's really needed. For example, as a method of Hibernate.initialize .

Thanks!

+4
source share
2 answers

lazy collections have been well tested and used by many others, so there may be errors with them, it is more likely that the lazy collection class is lying to you.

When each of the UserShow objects UserShow retrieved from the DAO, episodes will not be empty, but an instance of LazyForeignCollection will be set LazyForeignCollection . However, there will be no additional queries, and there will be no Episode data contained in the collection. If you then make a call to one of the methods in the collection, for example userShow.getEpisodes().iterator() , then a separate request will be made so that you can iterate over these episodes. The way lazy collections work.

If you still think that lazy collections do not work, please show us how you determine that there are episode data on the show. To find out what queries are running there, you can enable the Android log with ORMLite .


Edit:

It turns out that @Georgy used a debugger to examine the collection. The debugger most likely calls the same iterator() or toArray() methods that cause the collection request to be issued at this point. Thus, there were no episodes in the collection before the debugger asked for them.

+4
source

Your example should be fine. I created corresponding test tables and inserted 2 usershows and 3 episodes . Then I --general-log=<log file name> MySQL --general-log=<log file name> (set using MySQL with --general-log=<log file name> - see http://dev.mysql.com/doc/refman/5.5/en/query-log.html ).

Full Groovy script test:

 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 } 

Only one select statement is displayed in the log:

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

Change the last line to the following (which iterates over all users and gets the episode field for each of them:

 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 
+1
source

Source: https://habr.com/ru/post/1369641/


All Articles