ORMLite not loading child foreign fields

crpribeiro picture crpribeiro · Jan 22, 2013 · Viewed 9.2k times · Source

I'm using ORMLite 4.42 for an Android app. I have an entity which has foreign fields. These fields have foreign fields too. The problem is that when I get an element of the root entity, only the first level of foreign fields are loaded. The others levels are null.

On the database every seems ok. The id is correct. Any help?

Edit with models.


The Equipment model is always null when I query by ID. But if I query the whole table, then it gives me access to everything.

TABLE INCIDENT

@DatabaseField(generatedId=true)
private UUID id;
    
@DatabaseField(foreign=true, foreignAutoRefresh=true, canBeNull=false)
private UserEntity user;
    
@DatabaseField(dataType = DataType.DATE, canBeNull=true)
private Date date;
    
@DatabaseField(foreign=true, foreignAutoRefresh=true, canBeNull=true)
private EquipmentEntity equipment;

TABLE EQUIPMENT

@DatabaseField(generatedId=true)
private UUID id;
    
@DatabaseField(canBeNull=false, unique=true)
private String serial;
    
@DatabaseField(foreign=true, foreignAutoRefresh=true, canBeNull=false)
private EquipmentTypeEntity type;

TABLE EQUIPMENT TYPE

@DatabaseField(generatedId=true)
private UUID id;

@DatabaseField(canBeNull=true)
private String type;
    
@DatabaseField(foreign=true, foreignAutoRefresh=true, canBeNull=false)
private EquipmentModelEntity model;

TABLE EQUIPMENT MODEL

@DatabaseField(generatedId=true)
private UUID id;
    
@DatabaseField(canBeNull=false)
private String model;

Answer

Gray picture Gray · Jan 22, 2013

I'm using ORMLite 4.42 for an Android app. I have an entity which has foreign fields. These fields have foreign fields too. The problem is that when i get an element of the root entity, only the first level of foreign fields are loaded. The others levels are null.

Right, this is by design. ORMLite specifically limits the number of times it auto-refreshes a sub-element. This was done to protect against huge object trees swallowing memory and against self referential objects.

To quote the docs for foreignAutoRefresh:

NOTE: To protect against recursion, there are a couple of places were auto-refreshing has been limited. If you are auto-refreshing a class that itself has field with foreignAutoRefresh set to true or if you are auto-refreshing a class with a foreign collection, in both cases the resulting field will be set to null and not auto-refreshed. You can always call refresh on the field directly if you need it.

NOTE: If you have an auto-refreshed field that is an object that also has an auto-refreshed field, you may want to tune the maxForeignAutoRefreshLevel value. See below.

To quote from the docs for maxForeignAutoRefreshLevel:

This can be used to set the maximum number of levels to configure foreign objects. For example, if you have a Question which has an foreign field of the best Answer, and the Answer has an foreign field to the corresponding question, then the configuration back and forth can get large. This is especially a problem with auto-refreshed fields when you lookup the Question it could cause an infinite loop. By default, ORMLite only goes through 2 levels but you can decrease it to 1 (0 is not valid) or increase it. The higher the number the more database transactions happen when you load in your Question.

If you increase the maxForeignAutoRefreshLevel to be more then it will issue the extra queries to refresh the elements.

@DatabaseField(foreign=true, foreignAutoRefresh=true, canBeNull=true,
    maxForeignAutoRefreshLevel=3)
private EquipmentEntity equipment;