Hello I want persist some collections data with ORMlite in my android app. For example :
class Person {
@DatabaseField(generatedId=true)
private int id;
@DatabaseField
private String name;
@DatabaseField
private String surname;
@ForeignCollectionField
private Collections<Phone> phones;
}
class Phone {
@DatabaseField(generatedId=true)
private int id;
@DatabaseField
private String number;
@DatabaseField
private String type;
}
How i should do it to persist this collection.
EDIT
I use ForeignCollectionField as you told me. But now i have another question - is possible construction like that (I changed class a little)
@DatabaseTable
public class Student {
@DatabaseField(generatedId=true)
private int id;
@DatabaseField
private String name;
@DatabaseField
private String surname;
@DatabaseField
private String semestr;
@ForeignCollectionField
private Collection<Adres> adres;
}
public class Adres implements Serializable {
@DatabaseField(generatedId=true)
private int id;
@DatabaseField(foreign=true, columnName="student_id")
private Student student;
@DatabaseField
private String miasto;
@DatabaseField
private String ulica;
@DatabaseField
private String nr;
@ForeignCollectionField
private Collection<Phone> phone;
}
public class Phone {
@DatabaseField(generatedId=true)
private int id;
@DatabaseField
private String number;
@DatabaseField(foreign=true, columnName="adres_id" )
private Adres adres;
}
I build this structure, i have it in 3 tabelas.
Student queryForStudentMarcin = simpleDao.queryForId(studentMarcin.getId());
Collection<Adres> adres = queryForStudentMarcin.getAdres();
for (Adres a : adres) {
int id = a.getId();
String miasto = a.getMiasto();
String ulica = a.getUlica();
String nr = a.getNr();
}
Then i do this and error appear:
04-03 15:55:58.392: ERROR/AndroidRuntime(6506): FATAL EXCEPTION: main
04-03 15:55:58.392: ERROR/AndroidRuntime(6506): java.lang.NullPointerException
04-03 15:55:58.392: ERROR/AndroidRuntime(6506): at com.j256.ormlite.field.FieldType.buildForeignCollection(FieldType.java:579)
04-03 15:55:58.392: ERROR/AndroidRuntime(6506): at com.j256.ormlite.stmt.mapped.BaseMappedQuery.mapRow(BaseMappedQuery.java:58)
04-03 15:55:58.392: ERROR/AndroidRuntime(6506): at com.j256.ormlite.stmt.SelectIterator.nextThrow(SelectIterator.java:107)
04-03 15:55:58.392: ERROR/AndroidRuntime(6506): at com.j256.ormlite.stmt.SelectIterator.next(SelectIterator.java:120)
04-03 15:55:58.392: ERROR/AndroidRuntime(6506): at com.example.orm.MainActivity.dodajDoBazyCollection(MainActivity.java:140)
04-03 15:55:58.392: ERROR/AndroidRuntime(6506): at com.example.orm.MainActivity$2.onClick(MainActivity.java:66)
04-03 15:55:58.392: ERROR/AndroidRuntime(6506): at android.view.View.performClick(View.java:2408)
04-03 15:55:58.392: ERROR/AndroidRuntime(6506): at android.view.View$PerformClick.run(View.java:8816)
04-03 15:55:58.392: ERROR/AndroidRuntime(6506): at android.os.Handler.handleCallback(Handler.java:587)
04-03 15:55:58.392: ERROR/AndroidRuntime(6506): at android.os.Handler.dispatchMessage(Handler.java:92)
04-03 15:55:58.392: ERROR/AndroidRuntime(6506): at android.os.Looper.loop(Looper.java:123)
04-03 15:55:58.392: ERROR/AndroidRuntime(6506): at android.app.ActivityThread.main(ActivityThread.java:4627)
04-03 15:55:58.392: ERROR/AndroidRuntime(6506): at java.lang.reflect.Method.invokeNative(Native Method)
04-03 15:55:58.392: ERROR/AndroidRuntime(6506): at java.lang.reflect.Method.invoke(Method.java:521)
04-03 15:55:58.392: ERROR/AndroidRuntime(6506): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
04-03 15:55:58.392: ERROR/AndroidRuntime(6506): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
04-03 15:55:58.392: ERROR/AndroidRuntime(6506): at dalvik.system.NativeStart.main(Native Method)
Any suggestions ?
Edit2
Problem was read data from db. This procedure work ok, it's now nice, but i just use it to understand ORMlite. Thx very much Gray for help.
protected void czytajZBazy() throws SQLException {
Dao<Student, Integer> simpleDao = getHelper().getSimpleDao();
Dao<Adres, Integer> adresDao = getHelper().getAdresDao();
Dao<Phone, Integer> phoneDao = getHelper().getPhoneDao();
/**
* wyswietl adresy dla studenta Marcin
*/
QueryBuilder<Student, Integer> qbStudent = simpleDao.queryBuilder();;
Where<Student, Integer> where = qbStudent.where();
where.eq("name", "Marcin");
PreparedQuery<Student> prepare = qbStudent.prepare();
CloseableIterator<Student> iterator = simpleDao.iterator(prepare);
while(iterator.hasNext()){
Log.v("inside ", "loop");
Student next = iterator.next();
Log.v("sudent", ""+next.getId()+" "+next.getName()+" "+next.getSurname());
QueryBuilder<Adres, Integer> adresQB = adresDao.queryBuilder();
Where<Adres, Integer> where2 = adresQB.where();
where2.eq("student_id", next.getId());
PreparedQuery<Adres> preparedAdres = adresQB.prepare();
CloseableIterator<Adres> iterator2 = adresDao.iterator(preparedAdres);
while(iterator2.hasNext()){
Log.v("iterator po adresie", "!!");
Adres nextAdres = iterator2.next();
Log.v("Adres", ""+nextAdres.getId()+" "+nextAdres.getMiasto());
//wypisz telefony
QueryBuilder<Phone, Integer> queryPhone = phoneDao.queryBuilder();
Where<Phone, Integer> where3 = queryPhone.where();
where3.eq("adres_id", nextAdres.getId());
PreparedQuery<Phone> preparedPhone = queryPhone.prepare();
CloseableIterator<Phone> iterator3 = phoneDao.iterator(preparedPhone);
while(iterator3.hasNext()){
Log.v("inside phone iterator", "");
Phone next2 = iterator3.next();
Log.v("phone", ""+next2.getId()+" "+next2.getNumber());
}
iterator3.close();
}
iterator2.close();
}
iterator.close();
}
There are a number of resources and manuals that help with the usage of ORMLite under Android.
To persist a collection, you must first get a Dao for the class and then create each of the objects using the Dao:
Pretty much the same for your
Phone
class as well.He was really asking about how to use the
ForeignCollectionField
feature of ORMLite. The documentation for this can be found here:There is also an example project that uses it. In the above example, you are missing a
Person
field inside ofPhone
. If the person has a collection of phone objects then each phone object needs to have a corresponding person. This is called a "foreign object" in ORMLite.