Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
404 views
in Technique[技术] by (71.8m points)

android studio - I can auto increment id in room database but when refresh database it's shows double

In my app firstly i am fetching data from server using retrofit then it's saved in room database table then it shows in recyclerview but when i using a id as a primary key it's show only one data then this id i annotat autoGenerate = true then it's show all data which i put in server but when i reopen my app,it's show double data(this mean firstly i have 3 data in server,this app show 3 data but when i reopen or refresh my database it's show 6 data ,every time in refresh it's increasing).but i want this id will be increase but data will be not increase that's mean server have 3 data and it's store in room database table.

Movie.kt

@Entity(tableName = "movie_table")
data class Movie(
@PrimaryKey(autoGenerate = true)
var id: Int = 0,
@SerializedName("Title")
@Expose
val title: String,
@SerializedName("Year")
@Expose
val Year: Int,
@SerializedName("Genre")
@Expose
val genre: String,
@SerializedName("Language")
@Expose
val language: String,
@SerializedName("Country")
@Expose
val country: String,
@SerializedName("Poster")
@Expose
val poster: String,
@SerializedName("Plot")
@Expose
val plot:String
)

MovieDao.kt

@Dao
interface MovieDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertMovie(movie: Movie)

@Query("SELECT * FROM movie_table")
suspend fun getAllMovieDB(): List<Movie>

@Query("SELECT * FROM movie_table WHERE title LIKE :title")
suspend fun getSearchMovieDB(title: String): List<Movie>
}

MovieDatabase.kt

@Database(
entities = [Movie::class],
version = 1)
abstract class MovieDatabase: RoomDatabase() {
abstract fun getMovieDao(): MovieDao

companion object{
    @Volatile
    private var instance : MovieDatabase? = null
    private val LOCK = Any()
    operator fun invoke(context: Context) = instance
        ?: synchronized(LOCK){
            instance
                ?: buildDatabase(context).also{
                    instance = it
                }
        }
    private fun buildDatabase(context: Context) = Room.databaseBuilder(
        context.applicationContext,
        MovieDatabase::class.java,
        "movieDatabase"
    ).build()
}
}

Repository.kt

class Repository(context: Context) {
private val movieDao: MovieDao = MovieDatabase.invoke(context).getMovieDao()
private val movieCall = MovieApiClient.movieApi
suspend fun insertMovie(movie: Movie) {
    movieDao.insertMovie(movie)
}
suspend fun searchData(title: String): List<Movie> {
    return movieDao.getSearchMovieDB(title)
}
suspend fun getAllMovieDB(): List<Movie> {
    return movieDao.getAllMovieDB().also {
        getAllMovieFromServer()
    }
}
private suspend fun getAllMovieFromServer() {
    try {
        val movieList = movieCall.getAllMovie()
        movieList.forEach {
            insertMovie(it)
        }
    } catch (exception: Throwable) {
    }
}
}

better understanding with image (1)when id as a primary key without "autoGenerate = true" annotate enter image description here

(2)when id as a primary key with "autoGenerate = true" annotate enter image description here

How can I increase id without double data, How can i fix this? Please help me, Thank you.

question from:https://stackoverflow.com/questions/66046272/i-can-auto-increment-id-in-room-database-but-when-refresh-database-its-shows-do

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Looks like you are not fetching the movie ID from the server. This means that there is no way for you to know when a specific movie already exists in your DB, which is why it gets "duplicated".

To fix this simply make sure to fetch the movie ID from the server, too, along with all the other movie data. And remove the "autoGenerate = true" since you'll be using your own IDs.

This will ensure that when a movie that already exists in your DB is fetched from the server, there will be a conflict in the insert query, and since you used "(onConflict = OnConflictStrategy.REPLACE)" it will update the row with the new data.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...