Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Spring data exercise: repair a receipt query missing its tenant predicate

Last updated: 30 Sept 20264 min read
tutorial
IntermediateBy AITrove Editorial

A receipt lookup keyed only by receipt ID can select another tenant's row when IDs are reused across tenants.

Download Spring source kit

Repair the query and prove it

Start with a conceptual lookup that selects by receipt_id alone. The fixture stores R-41 twice: tenant-east has accepted and tenant-west has held. Add tenant_id to the SQL predicate and bind the trusted tenant from authentication. Then assert that east returns accepted, west returns held only for an authorized west identity, and a third tenant returns no row. Do not rely on an ORDER BY to hide the duplicate ID.

The source-kit tenant predicate lesson contains the repaired lookup. Its web test also denies an east token requesting the west route. Those are separate checks: a correct query does not make an untrusted tenant parameter trustworthy, and a correct service rule does not excuse an unscoped repository method.

Add a write trace

Change the read to update state. Include both receipt_id and tenant_id in the WHERE clause, and check that the affected row count is exactly one. If zero, distinguish not-found, stale version and unauthorized access according to the API's disclosure policy. The current fixture checks a read predicate, not a database write or row-level security. Run the named JUnit test locally; this exercise has no hosted judge.

Checked source

Java
String sql = "select state from tenant_receipt "
    + "where receipt_id = ? and tenant_id = ?";
List<String> states = jdbc.queryForList(sql, String.class, "R-41", trustedTenant);

Verification boundary

JwtTenantBoundaryTest.scopedQueryExcludesRowsForOtherTenantValues runs in the downloadable Spring source kit. The excerpt is shortened; the kit contains the complete test.

Costs and limits

The test queries two H2 rows and an absent third tenant value. It does not exercise a production data set, index plan, write transaction or a user-to-tenant membership service. For a large table, inspect a composite index plan on the target engine.

Common Mistakes

  • Do not fetch by receipt ID alone and filter after the query.
  • Do not bind an unverified URL tenant into the repaired SQL.
  • Do not call a zero-row update success.

Read next

Spring JdbcTemplate tenant predicates: put ownership in the SQL query, Spring Security JWT tenant principal: map only a validated claim, Spring security exercise: trace four JWT request outcomes.

spring
spring-boot
tenant-query-exercise
Storage details