CRUD detection
codeanalyzer-java surfaces data-access patterns by detecting CRUD operations in method bodies and attaching them to the relevant callable. This lets you audit where an application reads from and writes to persistent storage without reading every method by hand.
Detection is dispatched per framework by a CRUDFinderFactory. Today JPA / Jakarta Persistence detection is fully implemented; Spring Data and JDBC finders exist but are currently stubs.
Where it appears
Section titled “Where it appears”Each callable carries two arrays:
{ crud_operations: JCRUDOperation[] // persistence operations (persist/find/merge/remove, ...) crud_queries: JCRUDQuery[] // query definitions (createQuery / createNamedQuery)}CRUD operations (JCRUDOperation)
Section titled “CRUD operations (JCRUDOperation)”{ line_number: number operation_type: "CREATE" | "READ" | "UPDATE" | "DELETE" target_table: string // reserved — not yet populated involved_columns: string[] // reserved — not yet populated condition: string // reserved — not yet populated joined_tables: string[] // reserved — not yet populated}JPA operation mapping
Section titled “JPA operation mapping”For JPA, calls on the EntityManager and on query objects map to operation types:
| Operation type | Detected from |
|---|---|
| CREATE | EntityManager.persist(...) |
| READ | EntityManager.find(...); query execution getResultList(), getSingleResult(), getFirstResult(), getMaxResults() |
| UPDATE | EntityManager.merge(...); query executeUpdate() |
| DELETE | EntityManager.remove(...) |
CRUD queries (JCRUDQuery)
Section titled “CRUD queries (JCRUDQuery)”Query definitions (as opposed to executions) are captured separately:
{ line_number: number query_arguments: string[] // the query string and any parameters query_type: "READ" | "WRITE" | "NAMED"}These come from EntityManager.createQuery(String) and EntityManager.createNamedQuery(String). The query_type is inferred from the query text:
query_type | Inferred when |
|---|---|
| READ | the query string begins with select |
| WRITE | the query string begins with update, delete, or insert |
| NAMED | the query was created via createNamedQuery(...) |
Coverage and limits
Section titled “Coverage and limits”- JPA / Jakarta Persistence — implemented as described above.
- Spring Data — finder present but stubbed; repository-derived queries are not yet classified.
- JDBC — finder present but stubbed; raw
Statement/PreparedStatementcalls are not yet classified. - The
target_table,involved_columns,condition, andjoined_tablesfields onJCRUDOperationare reserved for future enrichment and are not populated yet.
Using it downstream
Section titled “Using it downstream”analysis = CLDK(language="java").analysis(project_path="my-app")
for cls in analysis.get_classes(): for sig, m in analysis.get_methods_in_class(cls).items(): for op in m.crud_operations: print(f"{op.operation_type} at {cls}:{op.line_number}")Combine with entry-point and call-graph data to answer questions like “which externally-reachable methods perform writes?”