{"id":23034811,"url":"https://github.com/m-thirumal/erm-postgresql-spring-boot","last_synced_at":"2025-10-11T10:12:11.474Z","repository":{"id":148986904,"uuid":"229966190","full_name":"m-thirumal/erm-postgresql-spring-boot","owner":"m-thirumal","description":"Generate POJO \u0026 DAO (JdbcTemplate) ERM for PostgreSQL.","archived":false,"fork":false,"pushed_at":"2024-10-20T01:32:11.000Z","size":170,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-08T12:46:18.598Z","etag":null,"topics":["erm","jdbctemplate","postgresql"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/m-thirumal.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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":"2019-12-24T15:42:35.000Z","updated_at":"2024-10-20T01:32:14.000Z","dependencies_parsed_at":null,"dependency_job_id":"82665e4a-1b0f-4fef-9456-f013cde46da3","html_url":"https://github.com/m-thirumal/erm-postgresql-spring-boot","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/m-thirumal%2Ferm-postgresql-spring-boot","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/m-thirumal%2Ferm-postgresql-spring-boot/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/m-thirumal%2Ferm-postgresql-spring-boot/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/m-thirumal%2Ferm-postgresql-spring-boot/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/m-thirumal","download_url":"https://codeload.github.com/m-thirumal/erm-postgresql-spring-boot/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246900435,"owners_count":20852053,"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":["erm","jdbctemplate","postgresql"],"created_at":"2024-12-15T16:36:03.882Z","updated_at":"2025-10-11T10:12:06.440Z","avatar_url":"https://github.com/m-thirumal.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# erm-postgresql-spring-boot\n\nGenerate Pojo \u0026 JdbcTemplate (DAO) for PostgreSQL\n\n## To use swagger UI\n\n\u003ca href =\"http://localhost:21991/swagger-ui/index.html\"\u003eSwagger-UI\u003c/a\u003e\n\n## Configuration files\n\n1. src/main/resources/application.yml\n2. src/main/resources/application.properties\n3. src/main/resources/application-erm-target.yml\n\n## Other helper methods/classes\n\n```\n/**\n * \n */\npackage com.thirumal.persistence;\n\nimport java.sql.PreparedStatement;\nimport java.sql.SQLException;\nimport java.util.List;\nimport java.util.Optional;\nimport java.util.Set;\nimport java.util.function.BiConsumer;\nimport java.util.stream.Collectors;\n\nimport com.thirumal.exception.InternalServerException;\nimport com.thirumal.exception.ResourceNotFoundException;\n\nimport jakarta.validation.constraints.NotNull;\nimport lombok.Getter;\nimport lombok.ToString;\n\n/**\n * Generic Data Access Object interface for repository\n * All ICMS DAO must implement this interface\n * @author Thirumal[திருமால்]\n * @since 14/04/2017\n * @version 1.0\n */\npublic interface GenericDao \u003cT, I, S\u003e {\n   \n    /** Persist the new instance (Model) object into database, I will hold localeCd value */\n    Optional\u003cT\u003e create(T model, I identifier);\n    \n    /** Persist the new instance (Model) object into database, I will hold localeCd value */\n    Long insert(T model, I identifier);\n    \n    /** Retrieve an Optional\u003cobject\u003e that was previously persisted to the database using\n     *  the indicated identifier (contains primary key \u0026 locale Cd)\n     */\n    Optional\u003cT\u003e get(@NotNull I identifier);\n    \n    /** Retrieve an object that was previously persisted to the database using\n     *  the indicated identifier (contains primary key \u0026 locale Cd) and whereClause\n     */\n\n    /** Retrieve an Optional\u003cobject\u003e that was previously persisted to the database using\n     *  the indicated identifier (contains primary key \u0026 locale Cd) and whereClause\n     */\n    Optional\u003cT\u003e get(@NotNull I identifier, S whereClause);\n   \n    /**\n     * Retrieve all instance using identifier ( id \u0026 LocaleCd)\n     */\n    List\u003cT\u003e list(I identifier);\n    \n    /**\n     * Retrieve all instance using the indicated identifier (id\n     *  \u0026 localeCd) and where clause\n     */\n    List\u003cT\u003e list(I identifier, S whereClause);\n    \n    /**\n  \t * Count all instance using the indicated identifier (id\n     *  \u0026 localeCd) and where clause\n     */\n    int count(I identifier, S whereClause);\n    \n    /** Save changes made to a persistent object. */\n    Optional\u003cT\u003e update(T transientObject, I identifier);\n    \n    /** Heap Only Tuple to improve write performance in PostgreSQL\n     *  Try not to include indexed column in the hot update method\n     *  Refer for WHY: https://github.com/M-Thirumal/postgresql_reference/blob/master/hot_update/hot_update.md\n     */\n    Optional\u003cT\u003e hotUpdate(T transientObject, I identifier, S whereClause);\n    \n    /** Remove an object from persistent storage in the database */\n    int delete(T persistentObject);\n    \n    /** Remove all objects from persistent storage in the database\n     * using Identifier and where clause (mostly Foreign key)*/\n    int delete(I identifier, S whereClause);\n    \n    default int findAndDelete(I identifier) {\n    \treturn delete(get(identifier).orElseThrow(()-\u003enew ResourceNotFoundException(\"The requested object is not found in database\")));\n    }\n\t\n    /**\n     * @author Thirumal\n     * Enum for PostgreSQL constant \n     */\n\t@Getter@ToString\n\tenum postgreSqlConstant {\n\t\tINFINITY(\"infinity\"), //Should be used for end date\n\t\tINTEGER(\"INTEGER\"),\n\t\tTAGS(\"tags\"),\n\t\tICMS_SERVICE(\"icms_service\");\n\t\tprivate String constant;\n\t\tpostgreSqlConstant(final String constant) {\n\t\t\tthis.constant = constant;\n\t\t}\n\t}\n\t\n\t/**\n\t * Replace the string with in-values with default delimiter \",\" or the requested delimiter\n\t * @since 0.6\n\t * @param \u003cE extends Number\u003e\n\t * @param query\n\t * @param replaceString\n\t * @param inValues\n\t * @param delimitter\n\t * @return query with inValues\n\t */\n\tdefault \u003cE extends Number\u003e String setInvalues(String query, String replaceString, Set\u003cE\u003e inValues, String... delimitter) {\n\t\treturn query.replace(replaceString, inValues.stream().map(Object::toString)\n\t\t\t\t.collect(Collectors.joining(delimitter.length \u003e 0 ? delimitter[0]:\",\")));\n\t}\n\t\n\tdefault String setInvalues(String query, String replaceString, Set\u003cString\u003e inValues) {\n\t\tif (inValues == null || inValues.isEmpty()) {\n\t\t\tthrow new InternalServerException(\"SQL IN values cannot be empty\");\n\t\t}\n\t\treturn query.replace(replaceString, \"'\" + inValues.stream().map(Object::toString).collect(Collectors.joining(\"','\")) + \"'\");\n\t}\n\t\n\tdefault String getIncrementDecrementQuery(String tableName, String columnName, int incrementDecrementCount) {\n\t\tif (tableName == null || columnName == null) {\n\t\t\tthrow new ResourceNotFoundException(\"Table \u0026 column name can't be NULL\");\n\t\t}\n\t\treturn (\"UPDATE indsolv.{TABLE_NAME} AS t SET {COLUMN_NAME} = (SELECT {COLUMN_NAME} + \"\n\t\t\t\t+ incrementDecrementCount + \" FROM indsolv.{TABLE_NAME} AS t1 WHERE t1.{TABLE_NAME}_uid = t.{TABLE_NAME}_uid) WHERE t.{TABLE_NAME}_uid = ?\")\n\t\t\t\t.replace(\"{TABLE_NAME}\", tableName).replace(\"{COLUMN_NAME}\", columnName); \n\t}\n\t\n\t/**\n\t * Replace the STRING between 2 String (EXCLUSIVE)\n\t * @param originalString\n\t * @param startWord\n\t * @param endWord\n\t * @param replaceString\n\t * @return STRING WITH REPLACED STRING\n\t */\n\tstatic String replaceBetween2Words(String originalString, String startWord, String endWord, String replaceString) {\n\t\treturn originalString.replaceAll(\"(\"+startWord + \")[^\u0026]*(\"+endWord+\")\", \"$1\"+replaceString+\"$2\");\n\t}\n\t\n\t/**\n\t * Covert list query to pagination query\n\t * @param listQuery\n\t * @return Pagination Query with count\n\t */\n\tdefault String getPaginationQuery(String listQuery) {\n\t\tStringBuilder finalQuery = new StringBuilder();\n\t\tfinalQuery.append(\"WITH r_cnt AS (\");\n\t\tString countQuerySplit = replaceBetween2Words(listQuery, \"SELECT\", \"FROM\", \" COUNT(*) cnt \");\n\t\tString[] countQuerySplitArray = countQuerySplit.split(\"(?i) LEFT JOIN\");\n\t\tString firstPart = countQuerySplitArray[0];\n\t\tif (firstPart.contains(\"INNER JOIN\")) {\n\t\t\tfirstPart = firstPart.split(\"(?i) INNER JOIN\")[0];\n\t\t}\n\t\tfinalQuery.append(firstPart);\n\t\tString lastPart = countQuerySplitArray[countQuerySplitArray.length - 1].split(\"(?i) WHERE\")[1];\n\t\tlastPart = lastPart.split(\"(?i)ORDER\")[0].split(\"(?i)OFFSET\")[0].split(\"(?i)LIMIT\")[0];\n\t\tfinalQuery.append(\" WHERE \" + lastPart + \")\");\n\t\tfinalQuery.append(listQuery.replaceFirst(\"SELECT\", \"SELECT (SELECT cnt FROM r_cnt), \"));\n\t\treturn finalQuery.toString();\n\t}\n\t\n\tdefault String getPaginationQueryForTable(String listQuery) {\n\t\tStringBuilder finalQuery = new StringBuilder();\n\t\tfinalQuery.append(\"WITH r_cnt AS (\");\n\t\tString countQuerySplit = replaceBetween2Words(listQuery, \"SELECT\", \"FROM\", \" COUNT(*) cnt \");\n\t\tString[] countQuerySplitArray = countQuerySplit.split(\"(?i) ORDER\");\n\t\tString firstPart = countQuerySplitArray[0];\n\t\tfinalQuery.append(firstPart + \")\");\n\t\tfinalQuery.append(listQuery.replaceFirst(\"SELECT\", \"SELECT (SELECT cnt FROM r_cnt), \"));\n\t\treturn finalQuery.toString();\n\t}\n\t\n\tdefault void setValue(PreparedStatement ps, int index, Object value) throws SQLException {\n\t    switch (value) {\n\t        case null:\n\t            ps.setObject(index, null);\n\t            break;\n\t        case Integer intValue:\n\t            ps.setInt(index, intValue);\n\t            break;\n\t        case String stringValue:\n\t            ps.setString(index, stringValue);\n\t            break;\n\t        case Boolean booleanValue:\n\t            ps.setBoolean(index, booleanValue);\n\t            break;\n\t        case Double doubleValue:\n\t            ps.setDouble(index, doubleValue);\n\t            break;\n\t        case Float floatValue:\n\t            ps.setFloat(index, floatValue);\n\t            break;\n\t        case Long longValue:\n\t            ps.setLong(index, longValue);\n\t            break;\n\t        case Short shortValue:\n\t            ps.setShort(index, shortValue);\n\t            break;\n\t        case Byte byteValue:\n\t            ps.setByte(index, byteValue);\n\t            break;\n\t        case java.sql.Date dateValue:\n\t            ps.setDate(index, dateValue);\n\t            break;\n\t        case java.sql.Time timeValue:\n\t            ps.setTime(index, timeValue);\n\t            break;\n\t        case java.sql.Timestamp timestampValue:\n\t            ps.setTimestamp(index, timestampValue);\n\t            break;\n\t        default:\n\t            ps.setObject(index, value);\n\t            break;\n\t    }\n\t}\n\n}\n```\n\n#### New Data type mapping can be done in DbHelper.java\n\n### Contact Info\n\n\u003ca href=\"mailto:m.thirumal@hotmail.com?Subject=erm-postgresql-spring-boot\" target=\"_top\"\u003eThirumal\u003c/a\u003e\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fm-thirumal%2Ferm-postgresql-spring-boot","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fm-thirumal%2Ferm-postgresql-spring-boot","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fm-thirumal%2Ferm-postgresql-spring-boot/lists"}