When working on Android, does ORMLite only save shallow level objects? I have a data structure with nested Objects, both of which are newly created, and I would like to be able to save both of them with one call to dao.create()
For exmaple, I have the following Parent Class.
@DatabaseTable
public class Parent {
@DatabaseField(generatedId=true)
public int id;
@DatabaseField
public String name;
@DatabaseField
public Child child;
}
and the following Child Class.
@DatabaseTable
public class Child {
@DatabaseField(generatedId=true)
public int id;
@DatabaseField
public String name;
}
I want to be able to do the following.
Parent parent = new Parent();
parent.name = "ParentName";
Child child = new Child();
child.name = "ChildName";
parent.child = child;
// .. get helper and create dao object...
dao.create(parent);
When doing this, the parent object is persisted but not the child object and the auto-generated child_id
column in the parent table is set to 0. Is this normal behavior? Is there a way to have nested objects persisted and propagate the primary key up?
As of version 4.27 ORMlite supports the foreignAutoCreate and foreignAutoRefresh settings on the
@DatabaseField
annotation on a field:This means that you assign your
child
field and if theid
field on the child is not set when the parent is created then it to will be created. TheforeignAutoRefresh
means that when a parent is retrieved a separate SQL call will be made to get thechild
field populated.You can also have more control over when ORMLite makes the calls to the child object by creating the child before you create the parent.
One more thing to note is that without the
foreignAutoRefresh = true
when you query for a Parent object, the child object that you get back only has its id field retrieved. If the id is an auto-generated int (for example), then the above name field will not be retrieved until you do an update on the child object.For more documentation about this, see the online page about Foreign Object Fields.
Some Notes on this solution
(foreignAutoCreate = true) work only if the ID field is not set (null or 0) according to ORMlite documentation http://ormlite.com/javadoc/ormlite-core/com/j256/ormlite/field/DatabaseField.html
This only works if generatedId is also set to true for the child table according to ORMlite documentation.
As mentioned, this does not seem to be supported in the lite version. I wrote a simple recursive function to save all referenced objects. I had problems getting the generics to play nice so in the end I just removed them all. I also made a base Entity class for my db objects.
So here is what I wrote. If anyone can get the same code to work with proper generics, or can improve upon it, please feel free to edit.
Did you try this?
I'm using ORMLite 4.35.