Использование Retrofit и GreenDao с вложенными объектами json

Я хочу объединить Retrofit и GreenDao, но у меня проблема с вложенными объектами Json. Мои вложенные поля остаются пустыми.

Это Json DataStructure

[
    {
        "id": 1, 
        "street": "Streetname", 
        "zipcode": 12345, 
        "city": "MyCity", 
        "phone_number": "+123456789", 
        "position": "12.0000, 9.0000", 
        "company": {
            "title": "CompanyName", 
            "group": {
                "title": "GroupName"
            }
        }
    }
]

Мой DaoGenerator выглядит так

    Entity customItem = schema.addEntity("CustomItems");
    customItem.addIdProperty();
    customItem.addStringProperty("street");
    customItem.addIntProperty("zipcode");
    customItem.addStringProperty("city");
    customItem.addStringProperty("phone_number");
    customItem.addStringProperty("position");

    Entity company = schema.addEntity("Company");
    company.addIdProperty();
    company.addStringProperty("title");

    Entity group = schema.addEntity("Group");
    group.addIdProperty();
    group.addStringProperty("title");

    Property companyPropId = customItem.addLongProperty("companyId").notNull().getProperty();
    customItem.addToOne(company, companyPropId);

    Property groupPropId = company.addLongProperty("groupId").notNull().getProperty();
    company.addToOne(group, groupPropId);

Моя проблема в том, что customItem.getCompany() возвращает значение NULL, но значения "id" в "position" в порядке. Я не уверен, в чем проблема, так как мой класс CustomItem содержит член

private Company company;

и сеттер для компании, и я не вижу никакой опечатки.

public void setCompany(Company company) {
    if (company == null) {
        throw new DaoException("To-one property 'companyId' has not-null constraint; cannot set to-one to null");
    }
    synchronized (this) {
        this.company = company;
        companyId = company.getId();
        company__resolvedKey = companyId;
    }
}

2 ответа

Решение

Я запустил его, но у меня было несколько проблем.

1) Когда я захотел сохранить CustomItem, Company и Group, у меня возникла проблема, заключающаяся в том, что getCompany() и getGroup() возвращали значение null, поскольку они не возвращали элемент напрямую, а извлекали его из БД. Поэтому я добавил геттер в сгенерированный класс сущностей CustomItem, который просто возвращает члена компании. Теперь я смог вставить компанию в БД. Геттер выглядит так:

// KEEP METHODS - put your custom methods here
public Company getCompanyLocal() {
    return company;
}
// KEEP METHODS END

То же самое касается и компании, и группы. Но была другая проблема...

2) Второй проблемой была сущность "Группа", поскольку "группа" - это зарезервированное ключевое слово SQL. Я вижу одно решение и плохое решение этой проблемы:

  • Хороший вариант - изменить данные json с "group" на "business_group" и, соответственно, изменить ваши DAO. Готово.

  • Плохой обходной путь, если вы находитесь в такой же ситуации, как я, где вы не можете изменить JSON, вы можете сделать следующее. Я вообще не сохраняю группу, но могу получить к ней доступ через компанию. Это как-то появляется там. Поэтому я добавил метод получения в свой класс компании, как метод получения CustomItem выше. Это работает, но вы должны избегать этого. Так как вы не можете запросить вашу БД для группы или загрузить группу из БД.

Чтобы решить вторую проблему, добавьте этот код в генератор DAO:

beacon.addStringProperty("business_group"); //Daogenerator

И добавьте этот код в свой сетевой менеджер:

//add this into your network manager
FieldNamingStrategy strategy = new FieldNamingStrategy() {
        @Override
        public String translateName(Field field) {
            if(field.getName().equalsIgnoreCase("business_group")) {
                return "group";
            } else {
                return field.getName();
            }
        }
    };

И установите это свойство для вашего Gson:

//add this in your Gson
.setFieldNamingStrategy(strategy)

надеюсь, это поможет!

Другие вопросы по тегам