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.
http://ormlite.com/docs/android
http://ormlite.com/docs/android-examples
To persist a collection, you must first get a Dao for the class and then create each of the objects using the Dao:
Dao<Person, Integer> personDao =
DaoManager.createDao(androidConnectionSource, Person.class);
for (Person person : personCollection) {
personDao.create(person);
}
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 of Phone
. 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.