{"id":20474210,"url":"https://github.com/marschall/jfr-jdbctemplate","last_synced_at":"2025-09-25T01:30:29.827Z","repository":{"id":44858670,"uuid":"160792956","full_name":"marschall/jfr-jdbctemplate","owner":"marschall","description":"an implementation of Spring JdbcTemplate that generates Flight Recorder events","archived":false,"fork":false,"pushed_at":"2024-12-18T19:26:21.000Z","size":578,"stargazers_count":4,"open_issues_count":1,"forks_count":0,"subscribers_count":5,"default_branch":"master","last_synced_at":"2024-12-18T20:24:40.002Z","etag":null,"topics":["java-flight-recorder","jdbctemplate","spring-jdbctemplate"],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/marschall.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-12-07T08:14:28.000Z","updated_at":"2024-12-18T19:26:25.000Z","dependencies_parsed_at":"2024-11-15T14:30:59.704Z","dependency_job_id":"08fbc129-c5ea-44cf-8e65-621c5b31b7ae","html_url":"https://github.com/marschall/jfr-jdbctemplate","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marschall%2Fjfr-jdbctemplate","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marschall%2Fjfr-jdbctemplate/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marschall%2Fjfr-jdbctemplate/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marschall%2Fjfr-jdbctemplate/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/marschall","download_url":"https://codeload.github.com/marschall/jfr-jdbctemplate/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":234141848,"owners_count":18785895,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["java-flight-recorder","jdbctemplate","spring-jdbctemplate"],"created_at":"2024-11-15T14:28:36.661Z","updated_at":"2025-09-25T01:30:24.516Z","avatar_url":"https://github.com/marschall.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"JFR JdbcTemplate [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.github.marschall/jfr-jdbctemplate/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.github.marschall/jfr-jdbctemplate) [![Javadocs](https://www.javadoc.io/badge/com.github.marschall/jfr-jdbctemplate.svg)](https://www.javadoc.io/doc/com.github.marschall/jfr-jdbctemplate)\n================\n\nAn implementation of Spring [JdbcTemplate](https://docs.spring.io/spring/docs/current/spring-framework-reference/data-access.html#jdbc) that generates [Flight Recorder](https://openjdk.java.net/jeps/328) events.\n\nThis project requires Java 11 based on OpenJDK or later.\n\n```xml\n\u003cdependency\u003e\n  \u003cgroupId\u003ecom.github.marschall\u003c/groupId\u003e\n  \u003cartifactId\u003ejfr-jdbctemplate\u003c/artifactId\u003e\n  \u003cversion\u003e2.1.0\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\nVersions 1.x are intended for Spring 5.x / Java 11, versions 2.x are intended for Spring 6.x / Java 17.\n\n![Flight Recording of a JUnit Test](https://github.com/marschall/jfr-jdbctemplate/raw/master/src/main/javadoc/resources/Screenshot%20from%202019-05-13%2021-09-33.png)\n\nCompared to approaches based on `DataSource` an approach based on `JdbcTemplate` has the advantage that it captures a complete database interaction. For example if you process many rows the initial `PreparedStatement#execute()` might be fast but most of the time may be spent in `ResultSet#next()`. A `JdbcTemplate` based approach generates a single JFR event for the entire interaction that involves several JDBC method invocations.\n\n Spring Class                                                             | JFR Class                                                              |\n|-------------------------------------------------------------------------|------------------------------------------------------------------------|\n| `org.springframework.jdbc.core.JdbcOperations`                          | `com.github.marschall.jfr.jdbctemplate.JfrJdbcOperations`               |\n| `org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations` | `com.github.marschall.jfr.jdbctemplate.JfrNamedParameterJdbcOperations` |\n\nReported Attributes\n-------------------\n\n\u003cdl\u003e\n\u003cdt\u003eoperationName\u003c/dt\u003e\n\u003cdd\u003eThe name of the execute JDBC operation, this corresponds to the method name on \u003ccode\u003eJdbcOperations\u003c/code\u003e/\u003ccode\u003eJdbcTemplate\u003c/code\u003e.\u003c/dd\u003e\n\u003cdt\u003equery\u003c/dt\u003e\n\u003cdd\u003eThe SQL query string passed to the JDBC driver. May be missing especially if custom \u003ccode\u003eorg.springframework.jdbc.core.PreparedStatementCreator\u003c/code\u003e fail to implement \u003ccode\u003eorg.springframework.jdbc.core.SqlProvider\u003c/code\u003e.\u003c/dd\u003e\n\u003cdt\u003erowCount\u003c/dt\u003e\n\u003cdd\u003eIn the case of a \u003ccode\u003eSELECT\u003c/code\u003e the number of rows returned. In the case of an \u003ccode\u003eUPDATE\u003c/code\u003e or \u003ccode\u003eDELETE\u003c/code\u003e the number of rows affected. \u003ccode\u003e-1\u003c/code\u003e for a statement that does not return anything like a DDL. \u003ccode\u003e-2\u003c/code\u003e when no information about the number of rows is available.\u003c/dd\u003e\n\u003c/dl\u003e\n\nOverhead\n--------\n\nWe try to keep overhead to a minimum and have no additional allocations besides the JFR events. Besides the overhead of the event the only additional overhead is:\n\n* a wrapper around `JdbcTemplate`\n* a few `instanceof` operations and casts\n* a `finally` block\n* a capturing lambda for `#queryForStream` methods to record `Stream#close` as the end time of the event\n* a small wrapper around every `RowCallbackHandler`\n\nWe assume `org.springframework.jdbc.core.SqlProvider#getSql()` is a simple getter.\n\nUsage\n-----\n\n```java\n@Configuration\npublic class JdbcConfiguration {\n\n   @Autowired\n   private DataSource dataSource;\n\n   @Bean\n   public JdbcOperations jdbcOperations() {\n     return new JfrJdbcOperations(new JdbcTemplate(this.dataSource));\n   }\n\n   @Bean\n   public NamedParameterJdbcOperations namedParameterJdbcOperations() {\n     return new JfrNamedParameterJdbcOperations(new NamedParameterJdbcTemplate(this.jdbcOperations()));\n   }\n\n}\n```\n\nYou need something like the following JVM options to run Flight Recorder\n\n```\n-XX:StartFlightRecording:filename=recording.jfr\n-XX:FlightRecorderOptions:stackdepth=128\n```\n\nLimitations\n-----------\n\n* When the SQL query is not provided as a `String` but as a `PreparedStatementCreator` or `CallableStatementCreator` it has to implement `SqlProvider` for the query string to show up in the flight recording.\n* `JdbcTemplate#query(PreparedStatementCreator, PreparedStatementSetter, ResultSetExtractor)` is not available because it is defined on `JdbcTemplate` and not `JdbcOperations`.\n* Several spring-jdbc classes `AbstractJdbcCall`, `SimpleJdbcCall`, `StoredProcedure`, `RdbmsOperation`, `AbstractJdbcInsert`, `SimpleJdbcInsert` but also `JdbcTestUtils` and `JdbcBeanDefinitionReader` require a `JdbcTemplate` and do not work with `JdbcOperations`. We have a [pull request](https://github.com/spring-projects/spring-framework/pull/23066/files) open for this but it has not been merged yet.\n* `JdbcOperations#execute(ConnectionCallback)` can not provide any insight into what is executed inside, that would require integration with [marschall/jfr-jdbc](https://github.com/marschall/jfr-jdbc)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarschall%2Fjfr-jdbctemplate","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmarschall%2Fjfr-jdbctemplate","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarschall%2Fjfr-jdbctemplate/lists"}