Repository navigation
feat: extract tzatziki-db (JDBC) and tzatziki-jpa (plain JPA) from tzatziki-spring-jpa - #868
alexandrepa wants to merge 35 commits into
Conversation
|
Re-apply the Jackson 3 support introduced on main (#927) after rebase: Jackson3PersistenceUtil now lives in tzatziki-jpa, shares the registered @transient annotations with PersistenceUtil, and JpaSteps registers the module matching the active mapper. Align test dependency versions. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
e4d7f4d to
ce66305
Compare
The 'the X repository will contain only' step no longer truncated the table and triggers were not disabled anymore. Restore both behaviours (re-enabling triggers in a finally block) and cover them with scenarios. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Downstream glue code calling SpringJPASteps methods (repository helpers, table/entity steps, autoclean flag) no longer compiled after the module split. Re-expose them as @deprecated(forRemoval) delegates to DatabaseSteps/JpaSteps/SpringJpaBackend, and propagate autoclean and schemasToClean to both JpaSteps and DatabaseSteps. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
The previous comparator compared the proxy class to the requested interface, which never matched, so a sub-interface repository (e.g. SuperUserDataSpringRepository for UserDataSpringRepository) could be picked depending on bean ordering, making tests flaky. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
SpringJpaBackend.saveAll used a manually created EntityManager with a RESOURCE_LOCAL transaction, bypassing Spring's transaction manager (and failing with JTA) as well as any custom repository logic. Prefer the entity's CrudRepository like the pre-split module did, falling back to the EntityManager only for entities without repository. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
JpaBackend.queryAll serialized entities with NON_DEFAULT inclusion, so false, 0 and null columns disappeared and could not be asserted with the table steps. Serialize with the full JSON mapper instead. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Once a JPA backend was registered, table steps on tables that are not mapped to an entity (join or audit tables) failed, although tzatziki-db alone supports them. Delegate those operations to a JdbcBackend. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
- Re-enable triggers in a finally block for every insertion step, so a failing insertion no longer leaves triggers disabled for later steps. - Remove JpaSteps' duplicated autoclean hook and configuration fields: DatabaseSteps already cleans every registered DataSource and is now the single owner of autoclean/schemasToClean. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
- DatabaseCleaner quotes schema/table names read from JDBC metadata, so mixed-case or special-character tables are truncated and get their triggers toggled instead of failing. - JdbcBackend.resolveColumnTypes splits schema.table into schema and table patterns (defaulting to the connection schema) and drops the duplicated lower-case fallback block. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…iki-jpa Drop the hard-coded hibernate-core 7.0.0.Final / jakarta.persistence-api 3.2.0 versions so the Spring Boot BOM manages them, and use provided scope so consumers keep the JPA implementation version of their application. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
EntityGraphUtils and JpaQueryUtils only looked at the first expected row, so associations asserted on later rows stayed uninitialized (null after the EntityManager closed). The expected structure of all rows is now merged, and lazy associations nested in collection elements are initialized as well. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
volatile/synchronized/CopyOnWriteArrayList did not make the shared static state safe for parallel scenarios (the locking on the CopyOnWriteArrayList was not even coordinated with its own mutations). Revert to plain collections as on main and document it in the ADR. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
The InsertSpec/SelectSpec/CountSpec/TruncateSpec records, their builders and SqlRenderer only served four statements built in two classes, and the TruncateSpec options were unused. Keep SqlIdentifier for validation and quoting, and render the statements with four static methods. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…n 2 paths - SqlIdentifier: possessive quantifiers in the identifier regex (S5998) - JpaBackend: ignore merge return value explicitly, compare Spring Data @table by class (S2201, S1872) - Tests for deprecated SpringJPASteps delegates, DatabaseCleaner exclusion filter / default overloads and the Jackson 2 PersistenceUtil module Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Spring's shared EntityManager proxy rejects getTransaction(), so entities only known through it could never be written. JPA entities are resolved through their LocalContainerEntityManagerFactoryBean, others through their Spring Data repository. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…ttributed to the module Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
- Reduce cognitive complexity of SpringJpaBackend.initialize, EntityGraphUtils.mergeShapes and JpaQueryUtils.initializeNestedAssociations - Roll back transactions in a finally block instead of catching Error - Read fields through Fields instead of setAccessible, set the default backend from a static method, use \w in SqlIdentifier Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…ASteps delegates Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…i-spring-jpa - Keep cucumber-picocontainer and tzatziki-jackson in compile scope in tzatziki-db/tzatziki-jpa and exclude cucumber-picocontainer in tzatziki-spring-jpa - Do not strip unasserted columns in JdbcBackend.queryAll and JpaBackend.queryAll so 'contains exactly' detects extra columns - Initialize lazy associations in SpringJPASteps.the_repository_contains via findAllWithExpectedFields - Fall back to @entity name / simple class name in JpaBackend.resolveTableName and avoid Map.entry NPE - Add SubGraph support for collection elements in EntityGraphUtils.addAttributesToGraph - Support DATE, TIME and TIMESTAMP/TIMESTAMPTZ conversion in JdbcBackend - Reset backend in DatabaseSteps.clearDataSources and fail with a clear IllegalStateException when no backend is registered - Fix false-positive trigger test, cover new cases, add module READMEs and regenerate steps-spring-jpa.md skill reference Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…re-split APIs - Table-level steps accept column names and schema-qualified table names (EntityTableMapping) - The table content variable contains entities again for mapped tables (DbBackend.contentOf) - Warn once per table when falling back to JDBC - Restore the pre-split SpringJPASteps constructor as deprecated - Increase db/jpa test coverage - Document Hibernate 6.2+ and PostgreSQL requirements Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…pa split - tzatziki-db: drop Sql/SqlIdentifier, JdbcTransactions and the column type conversion (untyped Types.OTHER parameters), one INSERT per row, single DataSource registry - tzatziki-jpa: concrete JpaBackend (no interface/PlainJpaBackend), @table based table resolution (no EntityTableMapping/column aliases), fetch graph only - tzatziki-spring-jpa: SpringJpaBackend extends JpaBackend, saves through the repository only, reads through the shared EntityManager Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
🟡 Changes recommended
Transaction-related blocking and runtime failures in JDBC fixtures and table resolution remain unresolved.
2 open findings
What changed in this PR
Splits persistence testing into JDBC, standalone JPA, and Spring Data layers, allowing applications to use database steps without depending on Spring.
Changes:
- Introduces
tzatziki-dbandtzatziki-jpa, with shared backend and configuration APIs. - Refactors Spring integration while retaining deprecated compatibility delegates.
- Adds regression coverage, module documentation, and build integration.
| File | Description |
|---|---|
| tzatziki-spring-jpa/src/test/resources/db/migration/V2__non_entity_table.sql | Adds an unmapped table fixture. |
| tzatziki-spring-jpa/src/test/resources/com/decathlon/tzatziki/steps/spring-jpa.feature | Expands Spring integration scenarios. |
| tzatziki-spring-jpa/src/test/java/com/decathlon/tzatziki/utils/SpringJpaBackendTest.java | Tests backend registration and transactions. |
| tzatziki-spring-jpa/src/test/java/com/decathlon/tzatziki/steps/RepositoryUsageSteps.java | Verifies repository invocation counts. |
| tzatziki-spring-jpa/src/test/java/com/decathlon/tzatziki/steps/LegacyApiSteps.java | Exercises compatibility delegates. |
| tzatziki-spring-jpa/src/test/java/com/decathlon/tzatziki/app/dao/VisibilityDataSpringRepository.java | Instruments fixture saves. |
| tzatziki-spring-jpa/src/main/java/com/decathlon/tzatziki/utils/SpringJpaBackend.java | Adds the Spring Data backend. |
| tzatziki-spring-jpa/src/main/java/com/decathlon/tzatziki/utils/EntityGraphUtils.java | Removes the Spring-local graph utility. |
| tzatziki-spring-jpa/src/main/java/com/decathlon/tzatziki/steps/SpringJPASteps.java | Delegates shared persistence operations. |
| tzatziki-spring-jpa/README.md | Documents shared configuration and transactions. |
| tzatziki-spring-jpa/pom.xml | Depends on the extracted JPA module. |
| tzatziki-jpa/src/test/resources/META-INF/persistence.xml | Defines standalone persistence units. |
| tzatziki-jpa/src/test/resources/com/decathlon/tzatziki/steps/jpa.feature | Covers standalone entity and table operations. |
| tzatziki-jpa/src/test/java/com/decathlon/tzatziki/utils/PersistenceUtilTest.java | Tests serialization filtering. |
| tzatziki-jpa/src/test/java/com/decathlon/tzatziki/steps/JpaTestSteps.java | Configures standalone JPA fixtures. |
| tzatziki-jpa/src/test/java/com/decathlon/tzatziki/JpaTest.java | Adds the JPA scenario runner. |
| tzatziki-jpa/src/test/java/com/decathlon/tzatziki/app/model/Shipment.java | Adds a schema-qualified entity fixture. |
| tzatziki-jpa/src/test/java/com/decathlon/tzatziki/app/model/Item.java | Adds a related entity fixture. |
| tzatziki-jpa/src/test/java/com/decathlon/tzatziki/app/model/Category.java | Adds a collection relationship fixture. |
| tzatziki-jpa/src/test/java/com/decathlon/tzatziki/app/model/Basket.java | Adds a many-to-many fixture. |
| tzatziki-jpa/src/main/java/com/decathlon/tzatziki/utils/PersistenceUtil.java | Makes transient filtering extensible. |
| tzatziki-jpa/src/main/java/com/decathlon/tzatziki/utils/JpaBackend.java | Implements entity operations and JDBC fallback. |
| tzatziki-jpa/src/main/java/com/decathlon/tzatziki/utils/Jackson3PersistenceUtil.java | Uses shared transient annotation registration. |
| tzatziki-jpa/src/main/java/com/decathlon/tzatziki/utils/EntityGraphUtils.java | Merges expected relationship shapes. |
| tzatziki-jpa/src/main/java/com/decathlon/tzatziki/steps/JpaSteps.java | Provides Spring-free entity steps. |
| tzatziki-jpa/README.md | Documents standalone JPA usage. |
| tzatziki-jpa/pom.xml | Defines the JPA module dependencies. |
| tzatziki-db/src/test/resources/com/decathlon/tzatziki/steps/db.feature | Covers JDBC database steps. |
| tzatziki-db/src/test/java/com/decathlon/tzatziki/utils/JdbcBackendTest.java | Tests transactions, defaults, and value conversion. |
| tzatziki-db/src/test/java/com/decathlon/tzatziki/steps/DatabaseTestSteps.java | Supplies database fixtures and assertions. |
| tzatziki-db/src/test/java/com/decathlon/tzatziki/steps/DatabaseStepsTest.java | Tests registration and step configuration. |
| tzatziki-db/src/test/java/com/decathlon/tzatziki/DatabaseTest.java | Adds the database scenario runner. |
| tzatziki-db/src/main/java/com/decathlon/tzatziki/utils/JdbcBackend.java | Implements raw JDBC table operations. |
| tzatziki-db/src/main/java/com/decathlon/tzatziki/utils/InsertionMode.java | Moves shared insertion modes. |
| tzatziki-db/src/main/java/com/decathlon/tzatziki/utils/DbBackend.java | Defines the table-operation contract. |
| tzatziki-db/src/main/java/com/decathlon/tzatziki/utils/DatabaseConfiguration.java | Shares legacy and new configuration fields. |
| tzatziki-db/src/main/java/com/decathlon/tzatziki/utils/DatabaseCleaner.java | Replaces Spring JDBC cleanup with plain JDBC. |
| tzatziki-db/src/main/java/com/decathlon/tzatziki/steps/DatabaseSteps.java | Centralizes table steps and trigger management. |
| tzatziki-db/README.md | Documents JDBC setup and behavior. |
| tzatziki-db/pom.xml | Defines the JDBC module dependencies. |
| skills/add-cucumber-tests/repomix/repomix.spring-jpa.json | Includes extracted step definitions. |
| skills/add-cucumber-tests/references/steps-spring-jpa.md | Refreshes the generated persistence reference. |
| report/pom.xml | Includes both modules in reporting. |
| README.md | Lists standalone database modules and Kafka. |
| pom.xml | Registers the new reactor modules. |
| docs/adr/001-jpa-module-decomposition.md | Records the layered design and compatibility decisions. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
tzatziki-spring-jpa only reached tzatziki-core transitively (via tzatziki-jpa and tzatziki-db), so tzatziki-spring brought cucumber-core first and its TestStep shadowed tzatziki-core's override: conditional guards (if ... =>) failed with SkipStepException instead of skipping the step. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
- JdbcBackend inserts empty rows with DEFAULT VALUES - JpaBackend treats names that are not loadable classes (e.g. AUDIT_LOGS) as non-entity tables instead of failing with ClassNotFoundException Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
steps-spring-jpa now only covers the Spring Data additions, like steps-spring-kafka builds on steps-kafka. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
|








Why
Database steps were only available through
tzatziki-spring-jpa, which requires a Spring context and Spring Data repositories. Projects without Spring, or using plain JDBC/JPA, could not reuse the table and entity steps.What
tzatziki-spring-jpais split into three layered modules. Each one reuses the steps of the module below it.tzatziki-db(new)tzatziki-corethe <table> table will contain / contains / contains nothing / is the <table> table content), trigger toggling, database cleanup (DatabaseCleaner,autoclean,schemasToClean) and aDbBackendSPI with a defaultJdbcBackendtzatziki-jpa(new)tzatziki-db, Hibernate 6the <Entity> entities will contain / contain …) andJpaBackend.JpaBackendroutes table steps to the entity whose@Tablematches, and falls back to JDBC for tables without an entity (e.g. join tables)tzatziki-spring-jpatzatziki-jpa,tzatziki-springSpringJpaBackend extends JpaBackend: inserts go through the Spring Data repositories, and reads go through Spring's sharedEntityManagerBackward compatibility
DatabaseStepsandJpaSteps.SpringJPAStepspublic API (constructor, step methods,autoclean,schemasToClean) is kept as@Deprecated(forRemoval = true)delegates.tzatziki-corestays the first dependency, so its Cucumber runner overrides (SkipStepExceptionhandling forif … =>guards) still win overcucumber-core.Validation
tzatziki-db(26),tzatziki-jpa(15),tzatziki-spring-jpa(36), on PostgreSQL via Testcontainers.Docs
docs/adr/001-jpa-module-decomposition.mdtzatziki-dbandtzatziki-jpa;tzatziki-spring-jpaREADME updatedadd-cucumber-testsskill: newsteps-db.mdandsteps-jpa.mdreferences (with their repomix configs);steps-spring-jpa.mdnow covers only the Spring Data additions;SKILL.mdtells which references to read for each module