-1

I'm using ORMLite (v4.48) with my Android app. I have the table "Contact" which can contain multiple "Email" (ForeignCollectionField) and one "Personal" (DatabaseField) object. When I get the Contact object from the database I would like to automatically get (or lazy load) the Personal object which has the same Contact ID.

It already automatically gets the Email objects which I can access. But for some reason the Personal object is always "null" even though there is an entry in the Personal table.

Here are my classes:

@DatabaseTable(tableName = "Contact", daoClass = ContactDao.class)
public class Contact {

    @DatabaseField(generatedId = true, columnName = PersistentObject.ID) 
    int id;

    @DatabaseField(index = true)
    String contactName;

    @ForeignCollectionField(eager = false)
    ForeignCollection<Email> emails;

    @DatabaseField(foreign = true)
    public Personal personal;

    public ForeignCollection<Email> getEmails() {
        return emails;
    }

    public void setEmails(ForeignCollection<Email> emails) {
        this.emails = emails;
    }

    public Personal getPersonal() {
        return personal;
    }

    public void setPersonal(Personal personal) {
        this.personal = personal;
    }
    ...
}   

And

@DatabaseTable(tableName = "Email", daoClass = EmailDao.class)
public class Email {

    @DatabaseField(generatedId = true, columnName = PersistentObject.ID)
    int id;

    @DatabaseField(foreign = true, foreignAutoRefresh = true, columnName = PersistentObject.CONTACT_ID_FIELD_NAME) // contact_id
    Contact contact;

    @DatabaseField
    String emailType;

    @DatabaseField(canBeNull = false)
    String email;

    public Email() {
    }

    public Email(int id, Contact Contact, String emailType, String email) {

        this.id = id;
        this.contact = contact;
        this.emailType = emailType;
        this.email = email;
    }

    public int getId() {

        return id;
    }

    public Contact getContact() {
        return contact;
    }

    public void setContact(Contact contact) {
        this.contact = contact;
    }

    public String getEmailType() {
        return emailType;
    }

    public void setEmailType(String emailType) {
        this.emailType = emailType;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    ...
}

and

@DatabaseTable(tableName = "Personal", daoClass = PersonalDao.class)
public class Personal {

    @DatabaseField(generatedId = true, columnName = PersistentObject.ID)
    int id;

    @DatabaseField(foreign = true, foreignAutoRefresh = true, columnName = PersistentObject.CONTACT_ID_FIELD_NAME)
    Contact contact;

    @DatabaseField
    int age;

    @DatabaseField
    int weight; // in grams

    @DatabaseField
    int height; // in cm

    public Personal() {
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public Contact getContact() {
        return contact;
    }

    public void setContact(Contact contact) {
        this.contact = contact;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public int getWeight() {
        return weight;
    }

    public void setWeight(int weight) {
        this.weight = weight;
    }

    public int getHeight() {
        return height;
    }

    public void setHeight(int height) {
        this.height = height;
    }

}

I'm getting the data from the database like this:

QueryBuilder<Contact, Integer> queryBuilder = mContactDao.queryBuilder();
queryBuilder.orderBy("lastViewed", false);
queryBuilder.limit(limit);

PreparedQuery<Contact> preparedQuery = queryBuilder.prepare();
List<Contact> contactList = mContactDao.query(preparedQuery);

that all works well so far. Then further down the code I can access the Email objects like this:

ForeignCollection<Email> emails = contact.getEmails();
Iterator<Email> iter = emails.iterator();
while (iter.hasNext()) {
    Email iAddress = iter.next();
    Log.d(TAG, "EMAIL: " + iAddress.getEmail());
    Log.d(TAG, "EMAIL TYPE: " + iAddress.getEmailType());
}

Which also works perfectly. Only if I want to access the Personal object I always get NULL.

Personal personal = contact.getPersonal(); // is always NULL

I can't figure out why that is. Do I manually need to add a JOIN in the query builder? I thought it would also lazily load the data once I access it with getPersonal() like it does with getEmails()?

Dominik
  • 1,703
  • 6
  • 26
  • 46

1 Answers1

1

You did not show how entity instances are created, but i assume Personal is created after Contact has been inserted. If that is a case, then after inserting Personal you should do contact.setPersonal(personal), and contactDao.update(contact) - that way personal_id will be stored in contact row

m.ostroverkhov
  • 1,910
  • 1
  • 15
  • 17
  • I haven't done it that way yet. Changed my code like you mentioned and it does add the Personal object to the Contact object. But when I read the Contact object from the database the Personal object is not NULL anymore but all the values I've entered are NULL except the referencing Contact ID in the Personal object. When I do a direct query for the Personal object I can see the entered values, though. – Dominik May 26 '16 at 20:15
  • adding foreignAutoRefresh = true in @DatabaseField should do the job. Also, instead you can fetch foreign field with personalDao.refresh(personal) – m.ostroverkhov May 27 '16 at 06:30
  • Thanks! "foreignAutoRefresh" was the missing part. Now it works how I wanted. Thanks a lot! – Dominik May 27 '16 at 20:06