I use a Room database class on Android Studio.
I have the following entities:
User, Address, Geo, Company, Album, Photo, AlbumPhotoCrossRef (there's many-to-many relationship between Album and Photo). And I added Word too just to test.
The code for these entities are added below.
When I use only Word (comment out other classes in the entities =
part, it works, I can see the table via DatabaseInspector.
But when include all entities, the database don't even open, I can't even see name of the database on DatabaseInspector.
And I get the following error:
E/AndroidRuntime: FATAL EXCEPTION: pool-2-thread-1 Process: com.example.lab8_2_room_albums, PID: 8775 java.lang.IllegalStateException: Room cannot verify the data integrity. Looks like you've changed schema but forgot to update the version number. You can simply fix this by increasing the version number. at androidx.room.RoomOpenHelper.checkIdentity(RoomOpenHelper.java:154) at androidx.room.RoomOpenHelper.onOpen(RoomOpenHelper.java:135) at androidx.sqlite.db.framework.FrameworkSQLiteOpenHelper$OpenHelper.onOpen(FrameworkSQLiteOpenHelper.java:142) at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:427) at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:316) at androidx.sqlite.db.framework.FrameworkSQLiteOpenHelper$OpenHelper.getWritableSupportDatabase(FrameworkSQLiteOpenHelper.java:92) at androidx.sqlite.db.framework.FrameworkSQLiteOpenHelper.getWritableDatabase(FrameworkSQLiteOpenHelper.java:53) at androidx.room.RoomDatabase.inTransaction(RoomDatabase.java:476) at androidx.room.RoomDatabase.assertNotSuspendingTransaction(RoomDatabase.java:281) at com.example.lab8_2_room_albums.dao.WordDao_Impl.insert(WordDao_Impl.java:57) at com.example.lab8_2_room_albums.MainActivity.lambda$onCreate$0(MainActivity.java:59) at com.example.lab8_2_room_albums.-$$Lambda$MainActivity$h9d6n2GFmqhE1uxj4ezb0-bRXOU.run(Unknown Source:2) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) at java.lang.Thread.run(Thread.java:923) I/Process: Sending signal. PID: 8775 SIG: 9
It refers to the line in the MainActivity where I run dao.insert(word) also where I insert a word. into database.
I did clean the project, rebuld the project too, but I still get the same error. Why? How to figure out what's wrong? And how can I fix this?
The database class is like below:
package com.example.lab8_2_room_albums.db; import android.content.Context; import androidx.annotation.NonNull; import androidx.room.Database; import androidx.room.Room; import androidx.room.RoomDatabase; import androidx.sqlite.db.SupportSQLiteDatabase; import com.example.lab8_2_room_albums.dao.PhotoDAO; import com.example.lab8_2_room_albums.dao.UserDAO; import com.example.lab8_2_room_albums.dao.WordDao; import com.example.lab8_2_room_albums.entities.Address; import com.example.lab8_2_room_albums.entities.Album; import com.example.lab8_2_room_albums.entities.AlbumPhotoCrossRef; import com.example.lab8_2_room_albums.entities.Company; import com.example.lab8_2_room_albums.entities.Geo; import com.example.lab8_2_room_albums.entities.Photo; import com.example.lab8_2_room_albums.entities.User; import com.example.lab8_2_room_albums.entities.Word; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @Database(entities = {Word.class, User.class, Address.class, Geo.class, Company.class, Album.class, Photo.class, AlbumPhotoCrossRef.class}, version = 1, exportSchema = true) public abstract class UserRoomDatabase extends RoomDatabase { //public abstract UserDAO userDAO(); // public abstract PhotoDAO photoDAO(); public abstract WordDao wordDao(); // volatile: har sammenheng med multithreading. Sikrer at alle tråder ser samme kopi av INSTANCE. private static volatile UserRoomDatabase INSTANCE; private static final int NUMBER_OF_THREADS = 4; public static final ExecutorService databaseWriteExecutor = Executors.newFixedThreadPool(NUMBER_OF_THREADS); public static UserRoomDatabase getDatabase(final Context context) { if (INSTANCE == null) { synchronized (UserRoomDatabase.class) { INSTANCE = Room.databaseBuilder(context.getApplicationContext(), UserRoomDatabase.class, "mydaaatabase") .addCallback(sRoomDatabaseCallback) .build(); } } return INSTANCE; } private static RoomDatabase.Callback sRoomDatabaseCallback = new RoomDatabase.Callback() { /** * Called when the database is created for the first time. * This is called after all the tables are created. * @param db */ @Override public void onCreate(@NonNull SupportSQLiteDatabase db) { super.onCreate(db); // If you want to keep data through app restarts, // comment out the following block databaseWriteExecutor.execute(() -> { // Populate the database in the background. WordDao wordDao = INSTANCE.wordDao(); //wordDao.deleteAll(); wordDao.insert(new Word("asd")); wordDao.insert(new Word("adsds")); wordDao.getAlphabetizedWords(); }); } @Override public void onOpen(@NonNull SupportSQLiteDatabase db) { super.onOpen(db); } }; /* static final Migration MIGRATION_1_2 = new Migration(1, 2) { @Override public void migrate(SupportSQLiteDatabase database) { database.execSQL("ALTER TABLE user " + " ADD COLUMN birth_year INTEGER"); } };*/ }
And here's the Main Activity:
package com.example.lab8_2_room_albums; import androidx.appcompat.app.AppCompatActivity; import androidx.lifecycle.ViewModelProvider; import androidx.room.Room; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.widget.Toast; import com.example.lab8_2_room_albums.dao.PhotoDAO; import com.example.lab8_2_room_albums.dao.UserDAO; import com.example.lab8_2_room_albums.dao.WordDao; import com.example.lab8_2_room_albums.databinding.ActivityMainBinding; import com.example.lab8_2_room_albums.db.UserRoomDatabase; import com.example.lab8_2_room_albums.entities.Address; import com.example.lab8_2_room_albums.entities.Album; import com.example.lab8_2_room_albums.entities.AlbumWithPhotos; import com.example.lab8_2_room_albums.entities.Company; import com.example.lab8_2_room_albums.entities.Geo; import com.example.lab8_2_room_albums.entities.Photo; import com.example.lab8_2_room_albums.entities.User; import com.example.lab8_2_room_albums.entities.UserWithAlbums; import com.example.lab8_2_room_albums.entities.UserWithCompanyWithAddressWithGeo; import com.example.lab8_2_room_albums.entities.Word; import com.example.lab8_2_room_albums.viewmodel.UserAlbumsViewModel; public class MainActivity extends AppCompatActivity { private UserAlbumsViewModel userAlbumsViewModel; private ActivityMainBinding activityMainBinding; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // ViewBinding: LayoutInflater layoutInflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE); activityMainBinding = ActivityMainBinding.inflate(layoutInflater); setContentView(activityMainBinding.getRoot()); // userAlbumsViewModel = new ViewModelProvider(this).get(UserAlbumsViewModel.class); UserRoomDatabase db = UserRoomDatabase.getDatabase(this); WordDao dao = db.wordDao(); UserRoomDatabase.databaseWriteExecutor.execute(() -> { // Populate the database in the background. // If you want to start with more words, just add them. Word word = new Word("Helloooo"); dao.insert(word); word = new Word("Woooorld"); dao.insert(word); dao.getAlphabetizedWords(); }); } }
I add some words into the words table in database. It works without any problem.
Word class:
package com.example.lab8_2_room_albums.entities; import androidx.annotation.NonNull; import androidx.room.ColumnInfo; import androidx.room.Entity; import androidx.room.PrimaryKey; @Entity(tableName = "word_table") public class Word { @PrimaryKey @NonNull @ColumnInfo(name = "word") private String mWord; public Word(@NonNull String word) {this.mWord = word;} public String getWord(){return this.mWord;} }
WordDAO:
package com.example.lab8_2_room_albums.dao; import androidx.lifecycle.LiveData; import androidx.room.Dao; import androidx.room.Insert; import androidx.room.OnConflictStrategy; import androidx.room.Query; import com.example.lab8_2_room_albums.entities.Word; import java.util.List; @Dao public interface WordDao { // allowing the insert of the same word multiple times by passing a // conflict resolution strategy @Insert(onConflict = OnConflictStrategy.IGNORE) void insert(Word word); @Query("DELETE FROM word_table") void deleteAll(); @Query("SELECT * FROM word_table ORDER BY word ASC") LiveData<List<Word>> getAlphabetizedWords(); }
User class:
package com.example.lab8_2_room_albums.entities; import androidx.annotation.NonNull; import androidx.room.Entity; import androidx.room.ForeignKey; import androidx.room.PrimaryKey; @Entity(foreignKeys = { @ForeignKey(entity = Address.class, parentColumns = "addressId", childColumns = "fk_addressId", onDelete = ForeignKey.CASCADE), @ForeignKey(entity = Company.class, parentColumns = "companyId", childColumns = "fk_companyId", onDelete = ForeignKey.CASCADE) }) public class User { @PrimaryKey(autoGenerate = true) public long userId; public String name; public String username; public String email; public long fk_addressId; public String phone; public String website; public long fk_companyId; public User(@NonNull String name, @NonNull String username, @NonNull String email, long fk_addressId, @NonNull String phone, @NonNull String website, long fk_companyId) { this.name = name; this.username = username; this.email = email; this.fk_addressId = fk_addressId; this.phone = phone; this.website = website; this.fk_companyId = fk_companyId; } }
Address:
package com.example.lab8_2_room_albums.entities; import androidx.annotation.NonNull; import androidx.room.Entity; import androidx.room.ForeignKey; import androidx.room.PrimaryKey; @Entity(foreignKeys = { @ForeignKey(entity = Geo.class, parentColumns = "geoId", childColumns = "fk_geoId", onDelete = ForeignKey.CASCADE) }) public class Address { @PrimaryKey(autoGenerate = true) public long addressId; public String street; public String suite; public String city; public String zipCode; public long fk_geoId; public Address(@NonNull String street, @NonNull String suite, @NonNull String city, @NonNull String zipCode, long fk_geoId) { this.street = street; this.suite = suite; this.city = city; this.zipCode = zipCode; this.fk_geoId = fk_geoId; } }
Geo:
package com.example.lab8_2_room_albums.entities; import androidx.annotation.NonNull; import androidx.room.Entity; import androidx.room.PrimaryKey; @Entity public class Geo { @PrimaryKey(autoGenerate = true) public long geoId; public double lat; public double lng; public Geo(@NonNull double lat, @NonNull double lng) { this.lat = lat; this.lng = lng; } }
Company:
package com.example.lab8_2_room_albums.entities; import androidx.annotation.NonNull; import androidx.room.Entity; import androidx.room.PrimaryKey; @Entity public class Company { @PrimaryKey(autoGenerate = true) public long companyId; public String name; public String catchPhrase; public String bs; public Company(@NonNull String name, @NonNull String catchPhrase, @NonNull String bs) { this.name = name; this.catchPhrase = catchPhrase; this.bs = bs; } }
Album:
package com.example.lab8_2_room_albums.entities; import androidx.annotation.NonNull; import androidx.room.Entity; import androidx.room.ForeignKey; import androidx.room.PrimaryKey; @Entity(foreignKeys = { @ForeignKey(entity = User.class, parentColumns="userId", childColumns = "fk_userId", onDelete = ForeignKey.CASCADE) }) public class Album { @PrimaryKey(autoGenerate = true) public long albumId; public long fk_userId; public String title; public Album(@NonNull String title, long fk_userId) { this.title = title; this.fk_userId = fk_userId; } }
Photo:
package com.example.lab8_2_room_albums.entities; import androidx.annotation.NonNull; import androidx.room.Entity; import androidx.room.PrimaryKey; @Entity public class Photo { @PrimaryKey(autoGenerate = true) public long photoId; public String title; public String url; public String thumbnailUrl; public Photo(@NonNull String title, @NonNull String url, @NonNull String thumbnailUrl) { this.title = title; this.url = url; this.thumbnailUrl = thumbnailUrl; } }
AlbumPhotoCrossRef:
package com.example.lab8_2_room_albums.entities; import androidx.room.Entity; import androidx.room.ForeignKey; @Entity(primaryKeys = {"albumId", "photoId"}, foreignKeys = { @ForeignKey(entity = Album.class, parentColumns="albumId", childColumns = "albumId", onDelete = ForeignKey.CASCADE), @ForeignKey(entity = Photo.class, parentColumns="photoId", childColumns = "photoId", onDelete = ForeignKey.CASCADE) } ) public class AlbumPhotoCrossRef { public long albumId; public long photoId; }
https://stackoverflow.com/questions/67039827/room-cant-build-database-in-android-studio-i-cant-figure-out-whats-wrong April 11, 2021 at 06:29AM
没有评论:
发表评论