-
Notifications
You must be signed in to change notification settings - Fork 269
BAH-4717|Shilpa|Forcing execution of SqlSearchService read only #323
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -42,14 +42,16 @@ public List<SimpleObject> search(String queryId, Map<String, String[]> params) | |
| SqlQueryHelper sqlQueryHelper = new SqlQueryHelper(); | ||
| String query = getSql(queryId); | ||
| debugPrintQueryParams(queryId, mergedParams); | ||
| try( Connection conn = DatabaseUpdater.getConnection(); | ||
| PreparedStatement statement = sqlQueryHelper.constructPreparedStatement(query,mergedParams,conn); | ||
| ResultSet resultSet = statement.executeQuery()) { | ||
| RowMapper rowMapper = new RowMapper(); | ||
| while (resultSet.next()) { | ||
| results.add(rowMapper.mapRow(resultSet)); | ||
| try (Connection conn = DatabaseUpdater.getConnection()) { | ||
| conn.setReadOnly(true); | ||
| try (PreparedStatement statement = sqlQueryHelper.constructPreparedStatement(query, mergedParams, conn); | ||
| ResultSet resultSet = statement.executeQuery()) { | ||
| RowMapper rowMapper = new RowMapper(); | ||
| while (resultSet.next()) { | ||
| results.add(rowMapper.mapRow(resultSet)); | ||
| } | ||
| return results; | ||
| } | ||
|
Comment on lines
+45
to
54
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Check how other services in the codebase handle transactions with JDBC
rg -n -B5 -A10 'DatabaseUpdater\.getConnection' --type=java
# Look for DataSource usage with `@Transactional` in the codebase
rg -nP -B2 -A8 '`@Transactional`.*\n.*DataSource' --type=java
# Check if there's a pattern of using Spring-managed connections elsewhere
rg -n -C5 'JdbcTemplate|DataSource' --type=java -g '*Service*.java'Repository: Bahmni/bahmni-core Length of output: 2500 🏁 Script executed: # Find the DatabaseUpdater class to understand getConnection()
fd -n "DatabaseUpdater.java" --type fRepository: Bahmni/bahmni-core Length of output: 293 🏁 Script executed: # Find the interface and method definition for the search method
rg -n "interface SqlSearchService|search\(" bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/SqlSearchServiceImpl.java -B 5 -A 15Repository: Bahmni/bahmni-core Length of output: 1319 🏁 Script executed: # Look for `@Transactional` annotation on this specific method
rg -n "`@Transactional`" bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/SqlSearchServiceImpl.java -B 2 -A 5Repository: Bahmni/bahmni-core Length of output: 44 🏁 Script executed: # Find DatabaseUpdater class
find . -name "DatabaseUpdater.java" -type fRepository: Bahmni/bahmni-core Length of output: 44 🏁 Script executed: # Find SqlSearchService interface definition
find . -name "SqlSearchService.java" -type fRepository: Bahmni/bahmni-core Length of output: 152 🏁 Script executed: # Look for class-level `@Transactional` on SqlSearchServiceImpl
rg -B 10 "public class SqlSearchServiceImpl" bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/impl/SqlSearchServiceImpl.javaRepository: Bahmni/bahmni-core Length of output: 358 🏁 Script executed: # Read the SqlSearchService interface to check for `@Transactional`
cat bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/SqlSearchService.javaRepository: Bahmni/bahmni-core Length of output: 498 🏁 Script executed: # Check if DatabaseUpdater is defined in this repo or if it's from OpenMRS
find . -name "DatabaseUpdater.java" -type fRepository: Bahmni/bahmni-core Length of output: 44 🏁 Script executed: # Search for other methods that use DatabaseUpdater.getConnection() to see if this is a pattern
rg -n "DatabaseUpdater" bahmnicore-api/src/main/java --type=javaRepository: Bahmni/bahmni-core Length of output: 369 🏁 Script executed: # Check if there are other `@Transactional` methods in the codebase and how they handle connections
rg -n "`@Transactional`" bahmnicore-api/src/main/java/org/bahmni/module/bahmnicore/service/ --type=java -A 3 | head -50Repository: Bahmni/bahmni-core Length of output: 6251 Address the mismatch between Spring transaction management and actual JDBC connection handling. The
Either remove the 🤖 Prompt for AI Agents |
||
| return results; | ||
| } catch (Exception e) { | ||
| throw new RuntimeException(e); | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
Repository: Bahmni/bahmni-core
Length of output: 15362
🌐 Web query:
Does OpenMRS DatabaseUpdater.getConnection() participate in Spring transaction management?💡 Result:
No, the OpenMRS DatabaseUpdater.getConnection method does not participate in Spring transaction management [1][2]. The method is designed to provide a raw database connection specifically for Liquibase to perform database schema updates [1][3][2]. Its implementation retrieves connection details directly from the OpenMRS runtime properties and establishes a new connection using DriverManager.getConnection [1]: public static Connection getConnection throws Exception { Properties props = Context.getRuntimeProperties; //... retrieves driver, url, username, password from properties... Class.forName(driver); return DriverManager.getConnection(url, username, password); } Because it uses DriverManager directly rather than a Spring-managed DataSource or a transaction-aware utility (such as Spring's DataSourceUtils), any connection obtained through this method operates outside the scope of Spring's transaction synchronization [4]. Consequently, it will not be aware of, nor participate in, any active Spring-managed transactions [4][5].
Citations:
The
@Transactionalannotation is ineffective withDatabaseUpdater.getConnection().OpenMRS's
DatabaseUpdater.getConnection()usesDriverManager.getConnection()directly and does not participate in Spring's transaction management. Any SQL executed on a connection obtained this way operates outside Spring's transaction scope and will not be aware of or participate in any active Spring-managed transactions. This makes the annotation misleading—it creates the false impression that the method is transaction-managed when the actual database operations are not.🤖 Prompt for AI Agents