Reputation: 8857
I noticed that since Room 2.3.0-alpha04
it supports Enum
field for the Entity
(from this post), so I try but failed...
My Gender
Enum:
enum class Gender(val value: String) {
MALE("Male"),
FEMALE("Female"),
UNKNOWN("Unknown")
}
My Entitiy
:
@Entity(tableName = "student")
data class Student(
var name: String,
var age: Int,
var gender: Gender //<- Enum
) {
@PrimaryKey(autoGenerate = true)
var id: Long = 0
}
My Dao
:
@Dao
interface StudentDao {
@Query("SELECT * FROM student")
fun getAllStudentsFlow(): Flow<List<Student>>
@Insert
suspend fun insert(student: Student)
@Query("SELECT COUNT(name) FROM student WHERE name = :name")
suspend fun getNameCount(name: String): Int
}
I'm using the latest version:
implementation "androidx.room:room-runtime:2.4.0-beta02"
implementation "androidx.room:room-ktx:2.4.0-beta02"
kapt "androidx.room:room-compiler:2.4.0-beta02"
And getting this error:
> Task :app:compileDebugJavaWithJavac FAILED
C:\...\com\example\roomwithenum\database\StudentDao_Impl.java:87: ����: ������
Student�еĹ����� StudentӦ�õ���������;
_item = new Student();
^
��Ҫ: String,int,Gender
�ҵ�: û�в���
ԭ��: ʵ�ʲ����б����ʽ�����б��Ȳ�ͬ
1 ������
Any help will be appreciated.
Upvotes: 0
Views: 812
Reputation: 56948
so I try but failed...
Well using you code and dependencies as per :-
dependencies {
implementation 'androidx.core:core-ktx:1.7.0'
implementation 'androidx.appcompat:appcompat:1.3.1'
implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.2'
implementation 'androidx.room:room-ktx:2.4.0-beta02'
implementation 'androidx.room:room-runtime:2.4.0-beta02'
implementation 'androidx.lifecycle:lifecycle-viewmodel-compose:2.4.0'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.0'
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.4.0'
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.4.0'
implementation 'androidx.lifecycle:lifecycle-viewmodel-savedstate:2.4.0'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
kapt 'androidx.room:room-compiler:2.4.0-beta02'
kapt 'androidx.lifecycle:lifecycle-compiler:2.4.0'
}
Then it compiles fine and the section of StudentDao_Impl that is garbled in your case compiles as ):-
@Override
public List<Student> call() throws Exception {
final Cursor _cursor = DBUtil.query(__db, _statement, false, null);
try {
final int _cursorIndexOfName = CursorUtil.getColumnIndexOrThrow(_cursor, "name");
final int _cursorIndexOfAge = CursorUtil.getColumnIndexOrThrow(_cursor, "age");
final int _cursorIndexOfGender = CursorUtil.getColumnIndexOrThrow(_cursor, "gender");
final int _cursorIndexOfId = CursorUtil.getColumnIndexOrThrow(_cursor, "id");
final List<Student> _result = new ArrayList<Student>(_cursor.getCount());
while(_cursor.moveToNext()) {
final Student _item;
final String _tmpName;
if (_cursor.isNull(_cursorIndexOfName)) {
_tmpName = null;
} else {
_tmpName = _cursor.getString(_cursorIndexOfName);
}
final int _tmpAge;
_tmpAge = _cursor.getInt(_cursorIndexOfAge);
final Gender _tmpGender;
_tmpGender = __Gender_stringToEnum(_cursor.getString(_cursorIndexOfGender));
_item = new Student(_tmpName,_tmpAge,_tmpGender);
final long _tmpId;
_tmpId = _cursor.getLong(_cursorIndexOfId);
_item.setId(_tmpId);
_result.add(_item);
}
return _result;
} finally {
_cursor.close();
}
}
@Override
protected void finalize() {
_statement.release();
}
});
About 2/3rds down is line _item = new Student(_tmpName,_tmpAge,_tmpGender);
Yours is garbled by this stage but is interestingly showing _item = new Student();
as if _tmpName _tmpAge and _tmpGender don't exist.
The garbled data is as if a byte stream has corrupted the generated code.
I'd suggest trying a clean and rebuild, perhaps exiting Android Studio and returning. There appears to be nothing wrong with your code
----
P.S. you commented in regard to TypeConverters saying I thought the new version will provide this automatically by default...
You are correct, in StudentDao_Impl it includes :-
private String __Gender_enumToString(final Gender _value) {
if (_value == null) {
return null;
} switch (_value) {
case MALE: return "MALE";
case FEMALE: return "FEMALE";
case UNKNOWN: return "UNKNOWN";
default: throw new IllegalArgumentException("Can't convert enum to string, unknown enum value: " + _value);
}
}
private Gender __Gender_stringToEnum(final String _value) {
if (_value == null) {
return null;
} switch (_value) {
case "MALE": return Gender.MALE;
case "FEMALE": return Gender.FEMALE;
case "UNKNOWN": return Gender.UNKNOWN;
default: throw new IllegalArgumentException("Can't convert value to enum, unknown value: " + _value);
}
}
P.S. I've also include your code in another answer that'd given compiled and run with beta02 and shows (after clicking Insert a few times) :-
So certainly no problems with your code.
Upvotes: 1
Reputation: 4075
Store enums in DB in primitive types like a string. Best pratice for you is using @TypeConverters
class TypeConverters {
@TypeConverter
fun toGender(value: String) = enumValueOf<Gender>(value)
@TypeConverter
fun fromGender(value: Gender) = value.name
}
And annotate your database class with
@TypeConverters(Converters::class)
refer https://developer.android.com/reference/android/arch/persistence/room/TypeConverter
Upvotes: 0