You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Extend Codeanalyzer to Capture Database Entries #100
Is your feature request related to a problem? Please describe.
The codeanalyzer currently lacks database operation analysis capabilities. It cannot detect, represent or analyze CRUD (Create, Read, Update, Delete) operations in Java classes, making it difficult to understand database interactions and data flow in applications.
Describe the solution you'd like
Add a CRUDOperation and CRUDQuery class to represent database operations with:
Detection of database-related methods/annotations:
Spring is actually a bit tricky. This is what we may have to do---
When we go the call site within a method say foo()...
Get the receiver type (recvType) and called method name (calledMethName) from the callsite.
If the receiver type (recvType) extends Repository (or Sub-Interfaces like JpaRepository), then do the following:
a. see if the calledMethName implicitly match CRUD operations based on naming conventions (e.g., findBy*, deleteBy*, save*).
b. Alternatively, check to see if the called method has a @Query annotation, and if so then decipher and categorize the custom query.
Methodological note
There is no explicit CURDQuery callsite per-se in Spring, it is the same callsite as CRUDOperation if the method called has @Query annotation. So, to populate the CRUDQuery object, we'll have to now get the annotation arguments too.
Moreover! The query in Spring can either be SQL or a dialect of SQL called JPQL. So the below tow are valid:
JPQL
@Query("SELECT u FROM User u WHERE u.name = :name")
List<User> findByName(Stringname);
Traditional SQL
@Query(value = "SELECT * FROM users WHERE name = :name", nativeQuery = true)
List<User> findByName(Stringname);
But, it seems like there are well maintained parsers for these two! Hibernate's HQL parser, and JSQLParser.
In JPA, there is an ambiguity with determining whether query.executeUpdate() is an UPDATE or a DELETE operation. Although the name says executeUpdate, the user can create a query using entityManager.createQuery which is a delete operation as below
Queryq = entityManager.createQuery("DELETE FROM User u WHERE u.status = 'inactive'");
And then somewhere else, they may call the executeUpdate() method.
q.executeUpdate();
Note that the above two examples needn't be in the same method or even in the same class. Take the below example for instance--
publicclassQueryBuilder {
publicstaticQueryfoo(EntityManagerem) {
returnem.createQuery("DELETE FROM User u WHERE u.status = 'inactive'");
}
}
Then, in some other class--
publicclassUserService {
publicvoidbar(EntityManagerem) {
QueryupdateQuery = QueryBuilder.foo(em);
updateQuery.executeUpdate(); // UPDATE operation, but the execution context doesn't reveal that directly
}
}
So, unless we do dataflow analysis on foo, then find the call site within foo to createQuery and then parse the SQL or JPQL string to determine if it's create or delete, we can't really know what exactly was executed.
Activity
rahlk commentedon Feb 7, 2025
🧠 Brain-dump 🧠
Spring is actually a bit tricky. This is what we may have to do---
When we go the call site within a method say
foo()...Get the receiver type (
recvType) and called method name (calledMethName) from the callsite.If the receiver type (
recvType) extendsRepository(or Sub-Interfaces likeJpaRepository), then do the following:a. see if the
calledMethNameimplicitly match CRUD operations based on naming conventions (e.g.,findBy*,deleteBy*,save*).b. Alternatively, check to see if the called method has a
@Queryannotation, and if so then decipher and categorize the custom query.Methodological note
There is no explicit
CURDQuerycallsite per-se in Spring, it is the same callsite asCRUDOperationif the method called has@Queryannotation. So, to populate theCRUDQueryobject, we'll have to now get the annotation arguments too.Moreover! The query in Spring can either be SQL or a dialect of SQL called JPQL. So the below tow are valid:
JPQL
Traditional SQL
But, it seems like there are well maintained parsers for these two! Hibernate's HQL parser, and JSQLParser.
rahlk commentedon Feb 8, 2025
🧠 Brain-dump 🧠
In JPA, there is an ambiguity with determining whether
query.executeUpdate()is an UPDATE or a DELETE operation. Although the name saysexecuteUpdate, the user can create a query usingentityManager.createQuerywhich is a delete operation as belowAnd then somewhere else, they may call the
executeUpdate()method.Note that the above two examples needn't be in the same method or even in the same class. Take the below example for instance--
Then, in some other class--
So, unless we do dataflow analysis on
foo, then find the call site within foo to createQuery and then parse the SQL or JPQL string to determine if it's create or delete, we can't really know what exactly was executed.