hi i am writing my database in kotlin and want that room data base to be used in java class .But on running it ,it is showing error that myAppdatabase is not implemented.
this is my Database cls
#Database(entities = arrayOf(Feedback::class),version = 1,exportSchema = true)
abstract class MyDatabase : RoomDatabase(){
abstract fun dao(): Dao
companion object {
private var INSTANCE: MyDatabase? = null
fun getInstance(context: Context): MyDatabase? {
if (INSTANCE == null) {
synchronized(MyDatabase::class) {
INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
MyDatabase::class.java, "feed.db").allowMainThreadQueries()
.build()
}
}
return INSTANCE
}
}
}
this is my java class
context=this.getActivity();
INSTANCE=MyDatabase.Companion.getInstance(context);
myDatabase= Room.databaseBuilder(this.getActivity().getApplicationContext(),MyDatabase.class, "feed.dp").fallbackToDestructiveMigration().build();
Related
In my project, I use the Singleton design pattern, add a companion object and a function that returns a database object instance. This will avoid creating multiple instances
database object through which the connection to the SQL server is established.
I have the following code to connect to the database:
// Annotates class to be a Room Database with a table (entity) of the Word class
#Database(entities = arrayOf(ShoppingList::class), version = 1, exportSchema = false)
public abstract class ShoppingListRoomDatabase : RoomDatabase() {
abstract fun shoppingListDao(): ShoppingListDao
companion object {
// Singleton prevents multiple instances of database opening at the
// same time.
#Volatile
public var INSTANCE: ShoppingListRoomDatabase? = null
fun getDatabase(context: Context, scope: CoroutineScope): ShoppingListRoomDatabase {
// if the INSTANCE is not null, then return it,
// if it is, then create the database
return INSTANCE ?: synchronized(this) {
val instance = Room.databaseBuilder(
context.applicationContext,
ShoppingListRoomDatabase::class.java,
"shopping_list_database"
).addCallback(ShoppingListDatabaseCallback(scope)).build()
INSTANCE = instance
// return instance
instance
}
}
}
}
private class ShoppingListDatabaseCallback(
private val scope: CoroutineScope
) : RoomDatabase.Callback() {
override fun onCreate(db: SupportSQLiteDatabase) {
super.onCreate(db)
ShoppingListRoomDatabase.INSTANCE?.let { database ->
scope.launch {
populateDatabase(database.shoppingListDao())
}
}
}
fun populateDatabase(shoppingListDao: ShoppingListDao) {
shoppingListDao.deleteAll()
var shoppingList = ShoppingList(1,"First List")
shoppingListDao.insert(shoppingList)
shoppingList = ShoppingList(2, "Second List!")
shoppingListDao.insert(shoppingList)
}
}
Interface:
#Dao
interface ShoppingListDao {
#Query("SELECT * FROM shopping_lists ORDER BY id ASC")
fun getOrderedShoppingLists(): Flow<List<ShoppingList>>
#Insert
fun insert(shoppingList: ShoppingList)
#Query("DELETE FROM shopping_lists")
fun deleteAll()
}
How can I get this database instance in another kotlin class to work with it?
I stuck at this problem
class InventoryApplication : Application() {
val database: ItemDatabase by lazy { ItemDatabase.getDatabase(this) }
}
Error class
Code image
I had the same issue, i was able to resolve it by going to the ItemRoomDatabase.kt file, change the INSTANCE variable in the companion object, to return a non-null type ItemRoomDatabase? and the getDataBase() function to return a type ItemRoomDatabase, rather than a RoomDatabase return type as requested in the codelab example.
Your final code in the ItemRoomDatabase.kt file should look something like this:
#Database(entities = [Item::class], version = 1, exportSchema = false)
abstract class ItemRoomDatabase : RoomDatabase() {
abstract fun itemDao(): ItemDao
companion object {
#Volatile
private var INSTANCE: ItemRoomDatabase? = null
fun getDatabase(context: Context): ItemRoomDatabase {
return INSTANCE ?: synchronized(this) {
val instance = Room.databaseBuilder(
context.applicationContext,
ItemRoomDatabase::class.java,
"item_database"
)
.fallbackToDestructiveMigration()
.build()
INSTANCE = instance
instance
}
}
}
}
I'm new to kotlin and room, after following an official android guide i ended up by setting my entities, my DAO and my Database,
the issue is i can't understand on how can i use the function from dao in my fragment...
So my Database looks like this:
#Database(entities = [Articolo::class], version = 1, exportSchema = false)
abstract class ArticoliDatabase: RoomDatabase() {
abstract val articoliDao: ArticoliDAO
companion object {
#Volatile
private var INSTANCE: ArticoliDatabase? = null
fun getInstance(context: Context): ArticoliDatabase {
synchronized(this) {
var instance = INSTANCE
if (instance == null) {
instance = Room.databaseBuilder(
context.applicationContext,
ArticoliDatabase::class.java,
"pdt_database"
)
.fallbackToDestructiveMigration()
.build()
INSTANCE = instance
}
return instance
}
}
}
}
Then in my fragment i've done the following:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
...
db = ArticoliDatabase.getInstance(requireContext())
}
And in the same fragment in my click function i'm doing the following to insert
db.articoliDao.insert(Articolo(barcode, qta))
But the app even doesn't build correctly by saying that
ArticoliDatabase_Impl does not exist
So what is the right way to initialize and use the room database with kotlin?
I just need to simply insert and show the data from the db in a listview that's it..
The problem is in the build.gradle file. Can you please check if your import of room library looks like:
annotationProcessor "androidx.room:room-compiler:$room"
Since you are using kotlin, you must use kapt for annotation processor dependencies
This is how your room dependencies should look like
implementation "androidx.room:room-runtime:$room"
implementation "androidx.room:room-ktx:$room"
kapt "androidx.room:room-compiler:$room"
Create Database class AppDatabase and Dao Interface
AppDatabase
#Database(
entities = [User::class, Quote::class],
version = 1
)
abstract class AppDatabase : RoomDatabase() {
abstract fun getUserDao(): UserDao
abstract fun getQuoteDao(): QuoteDao
companion object {
#Volatile
private var instance: AppDatabase? = 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,
AppDatabase::class.java,
"MyDatabase.db"
).build()
}
}
Dao Interface Here
#Dao
interface UserDao{
#Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun upsert(user: User) : Long
#Query("SELECT * FROM user WHERE uid = $CURRENT_USER_ID")
fun getuser() : LiveData<User>
}
Now in your fragment or activity you can insert and get user data by just craeting an object of dabase class as given below
private val db: AppDatabase
db=AppDatabase(context)
fun saveUser(user: User) = db.getUserDao().upsert(user)
fun getUser() = db.getUserDao().getuser()
I am writing an android application following the Android Architectural Components design.
This is the database class:
#Database(entities = [Authentication::class],version = 1, exportSchema = false)
abstract class AuthDB: RoomDatabase(){
abstract val authenticationDao :AuthenticationAccessObject
companion object{
#Volatile
private var INSTANCE: AuthDB? = null
fun getInstance(context: Context): AuthDB {
synchronized(this){
var instance = INSTANCE
if(instance == null){
instance = Room.databaseBuilder(
context.applicationContext,
AuthDB::class.java,
"authentication_database"
)
.fallbackToDestructiveMigration()
.build()
INSTANCE = instance
}
return instance
}
}
}
}
This is the Repository class:
class Repository2() {
private val database: AuthDB = AuthDB.getInstance(context = getContext())
private val daoA = database.authenticationDao
//Function to register a new user to system
fun insertAuth(userData: Any){
if (userData is Authentication){
daoA.insertAuth(userData)
} else {
throw IllegalArgumentException()
}
}
My target is that when I write the ViewModel, I want to create instance of Repository2 and call functions for example as follows:
var repo = Repository2()
repo.insertAuth(authenticationObject)
I am having problem giving context to getInstance in the Repository. The context should be such that when I instantiate the repository, it should automatically get the application context and instantiate the AuthDB database.
Until now,
I have tried to create Application class that extends Application and tried to get application context from there as suggested in another stackoverflow solution
Instantiated database with following code and failed:
private val database: AuthDB = AuthDB.getInstance(context = getContext())
Instantiated database with following code and failed:
private val database: AuthDB = AuthDB.getInstance(Application.getApplicationContext())
I have been trying for about two days now and nothing is working, I believe I am missing a major concept here. I hope someone can nudge me in the right direction?
Kind regards,
Salik
try this solution
EDIT:-
use this way to your RoomDatabase
#Database(
entities = [CompaniesModel::class, CompaniesHomeModel::class, UserPoint::class, Image::class, Offer::class, Rewords::class, BranchModel::class, PointsModel::class, RedeemModel::class, MainData::class, SubData::class],
version = 15)
abstract class DataBase : RoomDatabase() {
abstract fun homeDao(): HomeDao
abstract fun menuDao(): MenuDao
abstract fun companiesDao(): CompaniesListDao
abstract fun branchesDao(): BranchesDao
companion object {
#Volatile
private var databaseInstance: DataBase? = null
fun getDatabaseInstance(mContext: Context): DataBase =
databaseInstance ?: synchronized(this) {
databaseInstance ?: buildDatabaseInstance(mContext).also {
databaseInstance = it
}
}
private fun buildDatabaseInstance(mContext: Context) =
Room.databaseBuilder(mContext, DataBase::class.java, "crm")
.fallbackToDestructiveMigration()
.allowMainThreadQueries()
.build()
}
}
and for the getContext(), use Application() class like this:
class App : Application() {
override fun onCreate() {
super.onCreate()
instance = this
}
companion object {
lateinit var instance: App
}
}
and pass it like this
private val database: AuthDB = AuthDB.getInstance(app.instance)
I am new to android development and in my app I am using room database to make entry into database .
But i am getting this error in appManager_impl class
AppDatabase_Impl is not abstract and does not override abstract method appDao() in AppDatabase
public final class AppDatabase_Impl extends AppDatabase
My app manager class looks like this --
#Database(entities = [Data::class], version = 1, exportSchema = false)
abstract class AppDatabase : RoomDatabase() {
abstract fun appDao() : AppDao
companion object {
#Volatile
private var INSTANCE: AppDatabase? = null
fun getAppDatabase(context: Context, name : String): AppDatabase? {
if (INSTANCE == null) {
INSTANCE = Room.databaseBuilder(
context.applicationContext,
AppDatabase::class.java, name
).build()
}
return INSTANCE
}
fun destroyInstance() {
INSTANCE = null
}
}
}
The dependencies that I have used:
def roomDatabaseVersion = '2.3.0-alpha02'
implementation "androidx.room:room-ktx:$roomDatabaseVersion"
implementation "androidx.room:room-runtime:$roomDatabaseVersion"
kapt "androidx.room:room-compiler:$roomDatabaseVersion"
So, please aware to use kapt also.