房间 returns 生成的查询中的初始化对象不正确
Room returns incorrect initialized object from generated query
我有三个 table,一个包含 Cards,一个包含 CardDecks,第三个实现前两者之间的多对多关系,另外还包含每个关系条目的符号。
我的任务是从 card-table 中获取三列和 relation-table 中的符号,并将其保存在专门为处理这些输入而设计的数据对象中,编码为,所有条目都匹配给定的 deckId。或者(希望正确)sql-语言:
@Query("SELECT R.symbol, C.title, C.type, C.source " +
"FROM card_table C JOIN cards_to_card_deck R ON C.id = R.card_id"+
"WHERE R.card_deck_id = :cardDeckId")
LiveData<List<CardWithSymbol>> getCardsWithSymbolInCardDeckById(long cardDeckId);
但是房间实现 class 生成:
@Override
public LiveData<List<CardWithSymbol>> getCardsWithSymbolInCardDeckById(long
cardDeckId) {
final String _sql = "SELECT R.symbol, C.title, C.typ, C.source FROM
cards_to_card_deck R INNER JOIN card_table C ON R.card_id = C.id WHERE
R.card_deck_id = ?";
final RoomSQLiteQuery _statement = RoomSQLiteQuery.acquire(_sql, 1);
int _argIndex = 1;
_statement.bindLong(_argIndex, cardDeckId);
return new ComputableLiveData<List<CardWithSymbol>>() {
private Observer _observer;
@Override
protected List<CardWithSymbol> compute() {
if (_observer == null) {
_observer = new Observer("cards_to_card_deck","card_table") {
@Override
public void onInvalidated(@NonNull Set<String> tables) {
invalidate();
}
};
__db.getInvalidationTracker().addWeakObserver(_observer);
}
final Cursor _cursor = __db.query(_statement);
try {
final int _cursorIndexOfSymbol = _cursor.getColumnIndexOrThrow("symbol");
final List<CardWithSymbol> _result = new ArrayList<CardWithSymbol>(_cursor.getCount());
while(_cursor.moveToNext()) {
final CardWithSymbol _item;
final int _tmpSymbol;
_tmpSymbol = _cursor.getInt(_cursorIndexOfSymbol);
_item = new CardWithSymbol(_tmpSymbol,null,null,null);
_result.add(_item);
}
return _result;
} finally {
_cursor.close();
}
}
@Override
protected void finalize() {
_statement.release();
}
}.getLiveData();
}
其中
_item = new CardWithSymbol(_tmpSymbol,null,null,null);
应该 return 我完全初始化的对象。
CardWithSymbol class 声明如下:
public class CardWithSymbol {
public int symbol;
public String cardName;
public String cardType;
public String cardSource;
public CardWithSymbol(int symbol, String cardName, String cardType, String cardSource){
this.symbol = symbol;
this.cardName = cardName;
this.cardType = cardType;
this.cardSource = cardSource;
}
查询 return 列的类型是:
int symbol, String title, String 类型, String source
我已经进行了一些调试,应用程序的其余部分工作正常。我什至可以通过查询从对象 return 中读取符号,但如上所述,出于某种原因,room 忽略了其他三个参数,只是在查询实现中将它们默认为 null。
所以经过反复试验并再次阅读 dao 文档后,我发现了我的错误:
当创建一个 class 来处理 room 中列的子集时,重要的是通过 @ColumnInfo(name = "name of the column goes here")
-annotation 告诉 room 哪个变量对应于哪些列。
所以改变我的 CardWithSymbol class 如下解决了我的问题:
import android.arch.persistence.room.ColumnInfo;
public class CardWithSymbol {
@ColumnInfo(name = "symbol")
public int symbol;
@ColumnInfo(name = "title")
public String cardName;
@ColumnInfo(name = "type")
public String cardType;
@ColumnInfo(name = "source")
public String cardSource;
public CardWithSymbol(int symbol, String cardName, String cardType, String cardSource){
this.symbol = symbol;
this.cardName = cardName;
this.cardType = cardType;
this.cardSource = cardSource;
}
}
我有三个 table,一个包含 Cards,一个包含 CardDecks,第三个实现前两者之间的多对多关系,另外还包含每个关系条目的符号。
我的任务是从 card-table 中获取三列和 relation-table 中的符号,并将其保存在专门为处理这些输入而设计的数据对象中,编码为,所有条目都匹配给定的 deckId。或者(希望正确)sql-语言:
@Query("SELECT R.symbol, C.title, C.type, C.source " +
"FROM card_table C JOIN cards_to_card_deck R ON C.id = R.card_id"+
"WHERE R.card_deck_id = :cardDeckId")
LiveData<List<CardWithSymbol>> getCardsWithSymbolInCardDeckById(long cardDeckId);
但是房间实现 class 生成:
@Override
public LiveData<List<CardWithSymbol>> getCardsWithSymbolInCardDeckById(long
cardDeckId) {
final String _sql = "SELECT R.symbol, C.title, C.typ, C.source FROM
cards_to_card_deck R INNER JOIN card_table C ON R.card_id = C.id WHERE
R.card_deck_id = ?";
final RoomSQLiteQuery _statement = RoomSQLiteQuery.acquire(_sql, 1);
int _argIndex = 1;
_statement.bindLong(_argIndex, cardDeckId);
return new ComputableLiveData<List<CardWithSymbol>>() {
private Observer _observer;
@Override
protected List<CardWithSymbol> compute() {
if (_observer == null) {
_observer = new Observer("cards_to_card_deck","card_table") {
@Override
public void onInvalidated(@NonNull Set<String> tables) {
invalidate();
}
};
__db.getInvalidationTracker().addWeakObserver(_observer);
}
final Cursor _cursor = __db.query(_statement);
try {
final int _cursorIndexOfSymbol = _cursor.getColumnIndexOrThrow("symbol");
final List<CardWithSymbol> _result = new ArrayList<CardWithSymbol>(_cursor.getCount());
while(_cursor.moveToNext()) {
final CardWithSymbol _item;
final int _tmpSymbol;
_tmpSymbol = _cursor.getInt(_cursorIndexOfSymbol);
_item = new CardWithSymbol(_tmpSymbol,null,null,null);
_result.add(_item);
}
return _result;
} finally {
_cursor.close();
}
}
@Override
protected void finalize() {
_statement.release();
}
}.getLiveData();
}
其中
_item = new CardWithSymbol(_tmpSymbol,null,null,null);
应该 return 我完全初始化的对象。
CardWithSymbol class 声明如下:
public class CardWithSymbol {
public int symbol;
public String cardName;
public String cardType;
public String cardSource;
public CardWithSymbol(int symbol, String cardName, String cardType, String cardSource){
this.symbol = symbol;
this.cardName = cardName;
this.cardType = cardType;
this.cardSource = cardSource;
}
查询 return 列的类型是:
int symbol, String title, String 类型, String source
我已经进行了一些调试,应用程序的其余部分工作正常。我什至可以通过查询从对象 return 中读取符号,但如上所述,出于某种原因,room 忽略了其他三个参数,只是在查询实现中将它们默认为 null。
所以经过反复试验并再次阅读 dao 文档后,我发现了我的错误:
当创建一个 class 来处理 room 中列的子集时,重要的是通过 @ColumnInfo(name = "name of the column goes here")
-annotation 告诉 room 哪个变量对应于哪些列。
所以改变我的 CardWithSymbol class 如下解决了我的问题:
import android.arch.persistence.room.ColumnInfo;
public class CardWithSymbol {
@ColumnInfo(name = "symbol")
public int symbol;
@ColumnInfo(name = "title")
public String cardName;
@ColumnInfo(name = "type")
public String cardType;
@ColumnInfo(name = "source")
public String cardSource;
public CardWithSymbol(int symbol, String cardName, String cardType, String cardSource){
this.symbol = symbol;
this.cardName = cardName;
this.cardType = cardType;
this.cardSource = cardSource;
}
}