micronaut-projects / micronaut-projects/micronaut-data

JdbcRepository - support ability to tokenize and inject table name in @Query strings - particularly useful for inheritance

Open
#2,944 6 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

type: improvement
Dominant language
Java
Stars
482
Forks
229
Avg merge
1d 7h
Merged PRs (30d)
32

Description

Feature description

Consider a set of tables with a common set of base columns and a common set of queries that would apply to said columns.
Should the queries associated with the said columns not be achievable using the smart query finder method naming strategy, then one needs to leverage @Query("SELECT XXX FROM YYY WHERE ZZZ") style annotations.

It would be extremely useful if we could tokenize the table YYY piece above and automatically substitute with the entity model classes table name and thus not have to hardcode the table name in the query.

It is particularly relevant when using JdbcRepository inheritance ... e.g.


public interface RetryableOperationsTaskRepository<E extends RetryableOperationsTask, I extends Long> extends PageableRepository<E, I> {

@Executable
int updateTaskVisible(@Id I id, @Version Integer version, LocalDateTime visible);

List<RetryableOperationsTask> findAndLockApplicableTasks(final LocalDateTime visibleBefore, final int limit);

}


@JdbcRepository
public abstract class RetryableOperationsSalesTaskRepository implements RetryableOperationsTaskRepository<RetryableOperationsSalesTask, Long> {

@Query("SELECT * FROM RETRYABLE_OPERATIONS_SALES_TASK t WHERE t.VISIBLE < :visibleBefore ORDER BY t.ID ASC LIMIT :limit FOR UPDATE SKIP LOCKED")
@Executable
@Override
public abstract List<RetryableOperationsTask> findAndLockApplicableTasks(LocalDateTime visibleBefore, final int limit);

}


@JdbcRepository
public abstract class RetryableOperationsMarketingTaskRepository implements RetryableOperationsTaskRepository<RetryableOperationsMarketingTask, Long> {

@Query("SELECT * FROM RETRYABLE_OPERATIONS_MARKETING_TASK t WHERE t.VISIBLE < :visibleBefore ORDER BY t.ID ASC LIMIT :limit FOR UPDATE SKIP LOCKED")
@Executable
@Override
public abstract List<RetryableOperationsTask> findAndLockApplicableTasks(LocalDateTime visibleBefore, final int limit);

}


The only difference between the two overriding findAndLockApplicableTasks methods above is the table name.

Ideally we would not have needed to override these methods and instead could have inherited directly from the top-level interface.

However we currently have no way in the interface @Query to have some type of dynamic tokenized table_name that can be substituted in.

We are looking for something like the following in the top-level interface -

@Query("SELECT * FROM ${REPOSITORY_TABLE} t WHERE t.VISIBLE < :visibleBefore ORDER BY t.ID ASC LIMIT :limit FOR UPDATE SKIP LOCKED")
@Executable
@Override
List<RetryableOperationsTask> findAndLockApplicableTasks(LocalDateTime visibleBefore, final int limit);

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by tracing how JdbcRepository inheritance and @Query methods are processed. Inspect the repository and query handling entry points for a supported table-name token, then verify that an inherited query can substitute the concrete entity table name without overriding the method. No files or tests are named in the issue, so identify the relevant processing tests before making changes.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, sql
Domain
backend, database
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.