0

I am using Room Persistence Library and I am trying to avoid boilerplate code by creating a Generic DAO class, like this

@Dao
public interface PendingTaskDao<V>  {

    @Query("SELECT * FROM :tableName")
    Maybe<List<V>> getAllEntitiesFrom(String tableName);
}

But the compiler complains <table or subquery> expected got : tableName. Is there a way to create Generic DAO, or the library must work that way in order to prevent SQL injection?

4
  • You can probably build your own implementation, but what you want is not supported out of the box. Commented Apr 11, 2018 at 11:45
  • Thanks, it is obvious that I have to copy paste a lot :D Commented Apr 11, 2018 at 11:49
  • When that comes up, first question you have to ask yourself is "why do I actually need so many identical queries". It's not a good design for apps to materialize the whole table dataset into their memory, you probably made design error somewhere. Commented Apr 11, 2018 at 11:52
  • In fact you are right, I will have just two :D, but DAOs will the same except the names of classes. Commented Apr 11, 2018 at 12:01

2 Answers 2

1

the library must work that way in order to prevent SQL injection, yes, you're right.

From the docs of @Query:

This query is verified at compile time by Room to ensure that it compiles fine against the database.

So to let the query compile correctly, you must provide a tableName, not as a parameter, but directly in the query, hardcoded

Sign up to request clarification or add additional context in comments.

Comments

0

Though, you cannot create a generic DAO for all the operations for all the entities, you can at least create a BaseDao to commonize the insert, insertAll, update, updateAll, delete, and deleteAll operations.

/**
 * Created by Yousuf Sohail on 10/7/18.
 */
interface BaseDao<T> {

    /**
     * Insert an object or array of objects in the database.
     *
     * @param obj the objects to be inserted.
     */
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    fun insert(vararg obj: T): LongArray

    /**
     * Update an object or array of objects from the database.
     *
     * @param obj the object to be updated
     */
    @Update
    fun update(vararg obj: T)

    /**
     * Delete an object or array of objects from the database
     *
     * @param obj the object to be deleted
     */
    @Delete
    fun delete(vararg obj: T)
}

select and selectAll will go to specific Daos of entities.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.