JPA Hibernate Call Postgres Function Void Return MappingException:

前端 未结 7 2094
不知归路
不知归路 2020-12-31 11:38

I have a problem where I am getting an: org.hibernate.MappingException: No Dialect mapping for JDBC type: 1111 when trying to call a postgres function using JPA cre

7条回答
  •  南笙
    南笙 (楼主)
    2020-12-31 12:07

    This was posted some time ago, but I had the similar issue. As stated, Hibernate looks allergic to void and will try to lock you into using the return type every time. From my point of view, this is a good practice as you should normally always have a return at least to specify if it succeeded: throwing exception is often abusive.

    Yet, Hibernate DOES offer a way to bypass it's limitations: org.hibernate.jdbc.Work

    You can easily reproduce what was required in a small class:

    class VoidProcedureWork implements Work {
    
        String query;
    
        private VoidProcedureWork(String sql) {
            query = sql;
        }
    
        public static boolean execute(Session session, String sql) {
            try {
                // We assume that we will succeed or receive an exception.
                session.doWork(new VoidProcedureWork(sql));
                return true;
            } catch (Throwable e) {
                // log exception
                return false;
            }
        }
    
        /** 
         * @see org.hibernate.jdbc.Work#execute(java.sql.Connection)
         */
        @Override
        public void execute(Connection connection) throws SQLException {
            Statement statement = null;
            try {
                statement = connection.createStatement();
                statement.execute(query);
            } finally {
                if (statement != null)
                    statement.close();
            }
        }
    }
    

    Now you can call it whenever you want by using

    VoidProcedureWork.execute(hibernateSession, sqlQuery);

    You will notice two things about this class: 1) I do NOT close the Connection. I leave it that way because I do not know who opened the Connection, how and why. Is the same connection used in a transaction? If I close it ant someone uses it after, will it crash? Etc. I did not code Hibernate and did not use connection.open(). Therefore, I do not close it and assume whatever opened it will close it too. 2) It is more procedural programming than OOP. I know, but I am lazy: it is easier (and clearer imo) to use VoidProcedureWork.execute(session, sql) than new VoidProcedureWork(sql).execute(session). Or even worst: reproduce the code of execute everytime I want to use that little trick (session.doWork(new VoidProcedureWork(sql)) with exception processing).

提交回复
热议问题