Запрос обновления комнаты Android зависает на автоматически сгенерированном коде - PullRequest
0 голосов
/ 13 июня 2018

После использования Android Room в течение нескольких недель и получения базовых запросов я столкнулся с проблемой при попытке обновить список пользовательских объектов.По какой-то причине, когда Room пытается создать строку SQLLite для вставки моих новых данных, она застревает с заполнителями: из окна отладки:

Причина: android.database.sqlite.SQLiteException: near«?»: синтаксическая ошибка (код 1): при компиляции: UPDATE player_characters SETability_scores =?,?,?,?,?,?ГДЕ playerCharacterID =?################################################################# Код ошибки: 1 (SQLITE_ERROR) Причина: ошибка SQL (запрос) или отсутствует база данных.(рядом с «?»: синтаксическая ошибка (код 1): при компиляции: UPDATE player_characters SETability_scores =?,?,?,?,?,? WHERE playerCharacterID =?) ################################################################# at android.database.sqlite.SQLiteConnection.nativePrepareStatement (родной метод) в android.database.sqlite.SQLiteConnection.acquirePreparedStatement (SQLiteConnection.java:1005) в android.database.sqlite.SQLiteConnection.prepction.Conv: SQLite) в android.database.sqlite.SQLiteSession.prepare (SQLiteSession.java:588) в android.database.sqlite.SQLiteProgram. (SQLiteProgram.java:59) в android.database.sqlite.SQLiteStatement. (SQLiteStatement.java:31)на android.database.sqlite.SQLiteDatabase.compileStatement (SQLiteDatabase.java:1375) на android.arch.persistence.db.framework.FrameworkSQLiteDatabase.compileStatement (FrameworkSQLiteDatabase.java:62) на android.arch.persistence.room.RoomDatabase.compileStatement(RoomDatabase.java:204) в com.pathfinderstattracker.pathfindercharactersheet.database.database_daos.PlayerCharacterDao_Impl.updatePlayerCharacterAbilityScores (PlayerCharacterDao_Impl.java:321)

DAO, содержащая запрос:

@Dao
@TypeConverters({UUIDConverter.class,
                 AbilityScoreConcreteConverter.class})
public interface PlayerCharacterDao
{       
    @Query("UPDATE player_characters "+
           "SET ability_scores = :playerCharacterAbilityScores "+
           "WHERE playerCharacterID = :characterIDToUpdate")
    void updatePlayerCharacterAbilityScores(UUID characterIDToUpdate, List<AbilityScore> playerCharacterAbilityScores);
}

, которая вызывает команду: repos:1010 *

private static class updatePlayerCharacterAbilityScoresAsyncTask extends AsyncTask<Object, Void, Void>
{
    private PlayerCharacterDao asyncPlayerCharacterDao;
    updatePlayerCharacterAbilityScoresAsyncTask(PlayerCharacterDao dao) {asyncPlayerCharacterDao = dao;}
    @Override
    protected Void doInBackground(final Object... params)
    {
        UUID playerCharacterID = (UUID)params[0];
        List<AbilityScore> updatedAbilityScores = (ArrayList<AbilityScore>)params[1];
        asyncPlayerCharacterDao.updatePlayerCharacterAbilityScores(playerCharacterID, updatedAbilityScores);
        return null;
    }
}

Я могу подтвердить, что данные поступают в запрос помещения правильно, и я попытался передать в запрос как конкретные, так и интерфейсные объекты, а также имел конвертер для отдельных объектов AbilityScore исписок объектов AbilityScore.Любая помощь будет принята с благодарностью!

РЕДАКТИРОВАТЬ: Несколько человек попросили обновить сущность, которая обновляется:

@Entity(tableName = "player_characters")
@TypeConverters({AlignmentEnumConverter.class,
                 HitPointsConverter.class,
                 DamageReductionConverter.class,
                 StringListConverter.class,
                 UUIDConverter.class,
                 StringListConverter.class,
                 AbilityScoreListConverter.class,
                 CombatManeuverConverter.class})
public class PlayerCharacterEntity
{
    @PrimaryKey
    @NonNull
    private UUID playerCharacterID;
    @ColumnInfo(name="character_name")
    private String playerCharacterName;
    @ColumnInfo(name="character_level")
    private int characterLevel;
    @ColumnInfo(name="concentration_check")
    private int concentrationCheck;
    @ColumnInfo(name="character_alignment")
    private AlignmentEnum characterAlignment;
    @ColumnInfo(name="total_base_attack_bonus")
    private int totalBaseAttackBonus;
    @ColumnInfo(name="total_hit_points")
    private IHitPoints totalHitPoints;
    @ColumnInfo(name="total_ac")
    private int totalAC;
    @ColumnInfo(name="damage_reduction")
    private IDamageReduction damageReduction;
    @ColumnInfo(name="languages_known")
    private List<String> languagesKnown;
    @ColumnInfo(name="ability_scores")
    private List<IAbilityScore> abilityScores;
    @ColumnInfo(name="combat_Maneuver_stats")
    private ICombatManeuver combatManeuverStats;
    @ColumnInfo(name="spell_resistance")
    private int spellResistance;
    @ColumnInfo(name="initiative")
    private int initiative;
    @ColumnInfo(name="fortitude_save")
    private int fortitudeSave;
    @ColumnInfo(name="reflex_save")
    private int reflexSave;
    @ColumnInfo(name="will_save")
    private int willSave;

    ~Getters/Setters and Constructors removed for brevity~
}

РЕДАКТИРОВАТЬ: Идля хорошей меры я подумал, что я бы включил @TypeConverter для AbilityScore (я вернул это к более ранней форме, которая использует интерфейсы, а не конкретные, так как это работает в другом месте кода, и разница, похоже, ничего не меняет):

public class AbilityScoreConverter
{
    @TypeConverter
    public IAbilityScore fromString(String value)
    {
        IAbilityScore formattedAbilityScore = new AbilityScore();
        String[] tokens = value.split(" ");
        formattedAbilityScore.setAmount(Integer.parseInt(tokens[0]));
        switch(tokens[1])
        {
            case "STR":
                formattedAbilityScore.setStat(AbilityScoreEnum.STR);
            case "DEX":
                formattedAbilityScore.setStat(AbilityScoreEnum.DEX);
            case "CON":
                formattedAbilityScore.setStat(AbilityScoreEnum.CON);
            case "INT":
                formattedAbilityScore.setStat(AbilityScoreEnum.INT);
            case "WIS":
                formattedAbilityScore.setStat(AbilityScoreEnum.WIS);
            case "CHA":
                formattedAbilityScore.setStat(AbilityScoreEnum.CHA);
            default:
                //This may cause issues down the line if a non existent enum gets in the db somehow, but we don't have any error handling yet
                //Todo: Add error handling
                formattedAbilityScore.setStat(AbilityScoreEnum.STR);
        }

        return formattedAbilityScore;
    }

    @TypeConverter
    public String toString(IAbilityScore value)
    {
        return value.toString();
    }
}

РЕДАКТИРОВАТЬ: Я очистил текст logcat, чтобы сосредоточиться только на проблемах Room / SQLLite.

1 Ответ

0 голосов
/ 22 июня 2018

После некоторых поисков я, к сожалению, был вынужден отказаться от обновления моей базы данных с помощью команды @Query, и вместо этого мне пришлось прибегнуть к использованию нотации Rooms по умолчанию @Update.Хотя это работает и корректно обновляет данные в базе данных, я не могу обновлять только определенные поля.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...