Home > Enterprise >  Entities and POJOs must have a usable public constructor. You can have an empty constructor or a con
Entities and POJOs must have a usable public constructor. You can have an empty constructor or a con

Time:01-01

I have a shop app , if we beginning from the start user is need to sign up (if this account already in database he need to login). I have room data base with dao, database classes.

In sing up fragment i have 2 edittext fields with hint email and password .

I already have fun that is checking fields for empty.

I have already done initialiazation for database class in my fragment.

When user is clicking a button sign up (in the sign up fragment) his data will save in room db and user will go next to the next fragment.

I have error in my DAO class I guess

The code is below.

UserModel 
@Entity(tableName = "user_table")
data class UserModel(
    @PrimaryKey(autoGenerate = true)
    val id: Int?,
    @ColumnInfo
    val email: String? = "",
    @ColumnInfo
    val password:String? = ""
)

FragmentForActivityMain

class FragmentForActivityMain : Fragment(R.layout.fragment_for_activity_main) {
    private lateinit var  binding :FragmentForActivityMainBinding


    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
       binding = FragmentForActivityMainBinding.inflate(inflater,container,false)
        return binding.root


    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        init()


    }

private fun init(){
    val viewModel = ViewModelProvider(this).get(fragmentmainviewmodel::class.java)
    viewModel.initdb()
    binding.buttontogologin.setOnClickListener {
        findNavController().navigate(R.id.action_fragmentForActivityMain_to_loginFragment)
    }
    binding.signupbutton.setOnClickListener {
        findNavController().navigate(R.id.action_fragmentForActivityMain_to_signUpFragment)
    }
}
}

Const File

import UserRepository.UserRepository

lateinit var repository:UserRepository

Class fragmentmainviewmodel

import Const.repository
import Room.Database.UserDB
import UserRepository.RepositoryAndDaoRealization
import android.app.Application
import androidx.lifecycle.AndroidViewModel

class fragmentmainviewmodel(application: Application):AndroidViewModel(application) {
    val context = application
fun initdb(){
    val daouser = UserDB.getadminDB(context).getDAO()
    repository = RepositoryAndDaoRealization(daouser)
}

}

DAO class

@Dao
interface UserDAO {



  @Insert(onConflict = OnConflictStrategy.REPLACE)
 suspend fun insertnewUser(user:UserModel)

 @Query("select * from USER_TABLE where email like email and password like password")
suspend fun validationforuser(userModel: UserModel)

@Query("select * from user_table")
fun getAllUser():LiveData<List<UserModel>>

Database

@Database (entities = [UserModel::class], version = 5, exportSchema = true)
abstract class UserDB:RoomDatabase(){
abstract fun getDAO(): UserDAO
companion object{
    private var database : UserDB?= null
    @Synchronized
    fun getadminDB(context: Context):UserDB{
        return if(database == null){
            database= Room.databaseBuilder(context,UserDB::class.java,"UserDatabase").build()
            database as UserDB
        }else{
        database as UserDB
        }
    }
}
}

SignUpFragment

import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.fragment.findNavController
import com.example.myapplication.Model.UserModel
import com.example.myapplication.R
import com.example.myapplication.databinding.FragmentSignUpBinding


class SignUpFragment : Fragment() {
 lateinit var binding:FragmentSignUpBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
binding = FragmentSignUpBinding.inflate(inflater)
        return binding.root

    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        init()
    }
    private fun init(){
val viewModel = ViewModelProvider(this).get(SingUpViewModel::class.java)
    binding.signupbuttoninsignupfragment.setOnClickListener {
        val espace = binding.EmailSpaceSignUp.text.toString()
        val pspace = binding.PasswordSpaceSignUp.text.toString()
        viewModel.insert(UserModel(email = espace, password = pspace, id = id )){}
        findNavController().navigate(R.id.action_signUpFragment_to_lastfragment)
        if(binding.EmailSpaceSignUp == null){
            Toast.makeText(context,"Email space is empty , you need to write some data there",Toast.LENGTH_SHORT).show()
        }
        if(binding.PasswordSpaceSignUp == null){
            Toast.makeText(context,"Password space is empty , you need to write some data there",Toast.LENGTH_SHORT).show()
        }
        if(binding.PasswordSpaceSignUp.length()<8){
            Toast.makeText(context,"Password is too short",Toast.LENGTH_SHORT).show()
        }
        if(binding.EmailSpaceSignUp.length()<18){
            Toast.makeText(context,"Email is too short",Toast.LENGTH_SHORT).show()
        }
    }
    }
}

SingUpViewModel

class SingUpViewModel: ViewModel() {

    fun insert(userModel: UserModel,onSuccess:()->Unit) =
        viewModelScope.launch(Dispatchers.IO) {
            repository.insertUser(userModel){
                onSuccess()
            }
        }


}

Class RepositoryAndDaoRealization

class RepositoryAndDaoRealization(private var dao:UserDAO):UserRepository {
    override val allusers: LiveData<List<UserModel>>
        get() = dao.getAllUser()

    override suspend fun insertUser(userModel: UserModel, onSuccess: () -> Unit) {
        dao.insertnewUser(userModel)
        onSuccess()
    }

    override suspend fun validateuser(userModel: UserModel, onSuccess: () -> Unit) {
        dao.validationforuser(userModel)
        onSuccess()
    }
}

UserRepository

interface UserRepository {
val allusers:LiveData<List<UserModel>>
suspend fun insertUser(userModel: UserModel,onSuccess:()->Unit)
suspend fun validateuser(userModel: UserModel,onSuccess: () -> Unit)
}

CodePudding user response:

Your issues are with:-

@Query("select * from USER_TABLE where email like email and password like password")
suspend fun validationforuser(userModel: UserModel)

Room cannot ascertain what to do with the output from the query.

So you need to have something like:-

suspend fun validationforuser(userModel: UserModel): List<UserModel>

So Room knows what you want to do with the output from the query.

However, Room will then complain about the parameter passed to the function as per:-

error: Query method parameters should either be a type that can be converted into a database column or a List / Array that contains such type. You can consider adding a Type Adapter for this.

You could instead use:-

@Query("select * from USER_TABLE where email like email and password like password")
suspend fun validationforuser(email: String, password: String): List<UserModel>

BUT then Room will complain as it doesn't know what to do with the email and password parameters as they are not coded within the query. As per:-

error: Unused parameters: email,password

So you could then use:-

@Query("select * from USER_TABLE where email like :email and password like :password")
suspend fun validationforuser(email: String, password: String): List<UserModel>

Noting that instead of passing a UserModel, that you should pass the email and password from the UserModel.

e.g.

dao.validationforuser(userModel.email,userModel.password)
  • Related