相关实体的GreenDao getter返回空列表

时间:2014-09-14 15:44:57

标签: java android greendao

我有一个Android应用程序,我在其中使用greenDAO来建模我的数据库。我有一个简单的场景,但我不明白我是如何使它工作的。我已经遵循了文档,但我必须遗漏一些东西。

我有3个实体:用户,图片和地址。用户有图片和地址。我的图片和地址的getter总是返回null。

    userEntity.getPicture(); -> returns null
    userEntity.getAddress(); -> returns null

这是我的GreenDAO设置

    Entity userEntity = schema.addEntity("User");
    userEntity.addIdProperty();
    userEntity.addStringProperty("firstName");
    userEntity.addStringProperty("lastName");

    Entity picture = schema.addEntity("Picture");
    picture.addIdProperty();
    picture.addByteArrayProperty("image");
    picture.addStringProperty("imageName");

    Entity address = schema.addEntity("Address");
    address.addIdProperty();
    address.addStringProperty("street");
    address.addIntProperty("houseNumber");
    address.addIntProperty("zipcode");
    address.addStringProperty("city");

    // a user can have multiple pictures but a picture is connected to one user
    Property pictureIdProperty = picture.addLongProperty("userId").getProperty();
    picture.addToOne(userEntity, pictureIdProperty).setName("user");
    userEntity.addToMany(picture, pictureIdProperty).setName("picture");

    // a user can have multiple addresses but an address is only connected to one user
    Property addressIdProperty = address.addLongProperty("userId").getProperty();
    address.addToOne(userEntity, addressIdProperty).setName("user");
    userEntity.addToMany(address, addressIdProperty).setName("address");

这是我测试关系的测试类

    DevOpenHelper helper = new DaoMaster.DevOpenHelper(getApplication(), "relation_test_db", null);
    SQLiteDatabase db = helper.getWritableDatabase();
    DaoMaster daoMaster = new DaoMaster(db);
    this.daoSession = daoMaster.newSession();

    UserDao userDao = this.daoSession.getUserDao();
    PictureDao pictureDao = this.daoSession.getPictureDao();
    AddressDao addressDao = this.daoSession.getAddressDao();

    // clear all data
    userDao.deleteAll();
    pictureDao.deleteAll();
    addressDao.deleteAll();

    /**
     * create data
     */
    User bill = new User(null);
    bill.setFirstName("Bill");
    bill.setLastName("Murray");

    Picture billsPicture = new Picture(null);
    billsPicture.setImage("BillsExamplePictureByteArray".getBytes());
    billsPicture.setImageName("BillsPictureName");

    Address billsAddress = new Address(null);
    billsAddress.setStreet("BillsStreet");
    billsAddress.setHouseNumber(42);
    billsAddress.setZipcode(12345);
    billsAddress.setCity("Wilmette");

    billsPicture.setUser(bill);
    billsAddress.setUser(bill);

    userDao.insert(bill);
    pictureDao.insert(billsPicture);
    addressDao.insert(billsAddress);

    User user = userDao.queryBuilder().list().get(0);
    ArrayList<Picture> billsPictureList = (ArrayList<Picture>) user.getPicture();
    ArrayList<Address> billsAddressList = (ArrayList<Address>) user.getAddress();

    if (billsPictureList == null || billsPictureList.size() == 0) {
        // contact Markus
        Toast.makeText(this, "Contact Stackoverflow", Toast.LENGTH_SHORT).show();
        return;
    }

    if (billsAddressList == null || billsAddressList.size() == 0) {
        // contact Markus
        Toast.makeText(this, "Contact Stackoverflow", Toast.LENGTH_SHORT).show();
        return;
    }

1 个答案:

答案 0 :(得分:3)

伊曼纽尔,

在尝试使用1对1关系保存对象时,我遇到了一些类似的问题。

在我greenDAO花了足够的时间后,我发现,所有&#34;关系&#34;对象应具有其父母&#34;的适当映射ID。在保存到DB之前。

所以我建议,如果您查看生成的setUserPicture实体的Address方法,您会看到类似的内容:

public void setUser(User user) {
    synchronized (this) {
        this.user = user;
        userId = user == null ? null : user.getId();
        user__resolvedKey = userId;
    }
}

关键是userId = user == null ? null : user.getId();

存在竞争条件,因为创建的User对象在实际保存到DB之前不会获取ID。如果它没有ID,则有可能setUser其关系实体无法正常工作。

在您的情况下,您可以尝试将保存顺序更改为:

//1. Save user to DB, this will give it ID  
userDao.insert(bill);  

//2. Set user entity with ID to its relational entities  
billsPicture.setUser(bill);  
billsAddress.setUser(bill);  

//3. Save relational entities  
pictureDao.insert(billsPicture);  
addressDao.insert(billsAddress);

希望我的回答对您有所帮助。