Handle DataIntegrityViolation exceptions in OCPP controller

XMLWordPrintable

    • Type: Improvement
    • Resolution: Fixed
    • Priority: Major
    • Component/s: OCPP, SolarUser
    • None

      The UserOcppController does not gracefully handle DB data validation constraints, causing system alerts from the uncaught exception ERROR log messages. For example the saveChargePoint method which generates exceptions like this:

      [2022-07-18 09:51:42.363] ERROR [http-nio-9081-exec-4422 ] n.s.c.w.s.WebServiceControllerSupport    DataIntegrityViolationException in request uri=/solaruser/api/v1/sec/user/ocpp/chargers?: org.springframework.dao.DataIntegrityViolationException: 
      ### Error updating database.  Cause: org.postgresql.util.PSQLException: ERROR: null value in column "model" violates not-null constraint
      ### The error may exist in URL [jar:file:/workspace/WEB-INF/lib/solarnet-ocpp-1.0.0.jar!/net/solarnetwork/central/ocpp/dao/mybatis/map/CentralChargePoint.xml]
      ### The error may involve net.solarnetwork.central.ocpp.domain.CentralChargePoint.insert-CentralChargePoint-Inline
      ### The error occurred while setting parameters
      ### SQL: INSERT INTO solarev.ocpp_charge_point (    id         , user_id    , node_id    , enabled     , reg_status     , conn_count    , ident    , vendor    , model    , serial_num    , box_serial_num    , fw_vers    , iccid    , imsi    , meter_type    , meter_serial_num   ) VALUES (    ?         , ?    , ?    , ?     , ?     , ?    , ?    , ?    , ?    , ?    , ?    , ?    , ?    , ?    , ?    , ?   )
      ### Cause: org.postgresql.util.PSQLException: ERROR: null value in column "model" violates not-null constraint
      ; ERROR: null value in column "model" violates not-null constraint
      [2022-07-18 09:51:42.465] WARN  [http-nio-9081-exec-4422 ] n.s.c.w.s.WebServiceControllerSupport    Root SQLException from 
      ### Error updating database.  Cause: org.postgresql.util.PSQLException: ERROR: null value in column "model" violates not-null constraint
      ### The error may exist in URL [jar:file:/workspace/WEB-INF/lib/solarnet-ocpp-1.0.0.jar!/net/solarnetwork/central/ocpp/dao/mybatis/map/CentralChargePoint.xml]
      ### The error may involve net.solarnetwork.central.ocpp.domain.CentralChargePoint.insert-CentralChargePoint-Inline
      ### The error occurred while setting parameters
      ### SQL: INSERT INTO solarev.ocpp_charge_point (    id         , user_id    , node_id    , enabled     , reg_status     , conn_count    , ident    , vendor    , model    , serial_num    , box_serial_num    , fw_vers    , iccid    , imsi    , meter_type    , meter_serial_num   ) VALUES (    ?         , ?    , ?    , ?     , ?     , ?    , ?    , ?    , ?    , ?    , ?    , ?    , ?    , ?    , ?    , ?   )
      ### Cause: org.postgresql.util.PSQLException: ERROR: null value in column "model" violates not-null constraint
      ; ERROR: null value in column "model" violates not-null constraint
      org.postgresql.util.PSQLException: ERROR: null value in column "model" violates not-null constraint
          at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2675) ~[postgresql-42.3.3.jar:42.3.3]
          at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2365) ~[postgresql-42.3.3.jar:42.3.3]
          at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:355) ~[postgresql-42.3.3.jar:42.3.3]
          at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:490) ~[postgresql-42.3.3.jar:42.3.3]
          at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:408) ~[postgresql-42.3.3.jar:42.3.3]
          at org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:166) ~[postgresql-42.3.3.jar:42.3.3]
          at org.postgresql.jdbc.PgPreparedStatement.execute(PgPreparedStatement.java:155) ~[postgresql-42.3.3.jar:42.3.3]
          at com.zaxxer.hikari.pool.ProxyPreparedStatement.execute(ProxyPreparedStatement.java:44) ~[HikariCP-4.0.3.jar:na]
          at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.execute(HikariProxyPreparedStatement.java) ~[HikariCP-4.0.3.jar:na]
          at org.apache.ibatis.executor.statement.PreparedStatementHandler.update(PreparedStatementHandler.java:47) ~[mybatis-3.5.7.jar:3.5.7]
          at org.apache.ibatis.executor.statement.RoutingStatementHandler.update(RoutingStatementHandler.java:74) ~[mybatis-3.5.7.jar:3.5.7]
          at org.apache.ibatis.executor.SimpleExecutor.doUpdate(SimpleExecutor.java:50) ~[mybatis-3.5.7.jar:3.5.7]
          at org.apache.ibatis.executor.BaseExecutor.update(BaseExecutor.java:117) ~[mybatis-3.5.7.jar:3.5.7]
          at org.apache.ibatis.executor.CachingExecutor.update(CachingExecutor.java:76) ~[mybatis-3.5.7.jar:3.5.7]
          at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:194) ~[mybatis-3.5.7.jar:3.5.7]
          at org.apache.ibatis.session.defaults.DefaultSqlSession.insert(DefaultSqlSession.java:181) ~[mybatis-3.5.7.jar:3.5.7]
          at jdk.internal.reflect.GeneratedMethodAccessor192.invoke(Unknown Source) ~[na:na]
          at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:na]
          at java.base/java.lang.reflect.Method.invoke(Unknown Source) ~[na:na]
          at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:427) ~[mybatis-spring-2.0.6.jar:2.0.6]
          at com.sun.proxy.$Proxy89.insert(Unknown Source) ~[na:na]
          at org.mybatis.spring.SqlSessionTemplate.insert(SqlSessionTemplate.java:272) ~[mybatis-spring-2.0.6.jar:2.0.6]
          at net.solarnetwork.central.dao.mybatis.support.BaseMyBatisGenericDaoSupport.handleInsert(BaseMyBatisGenericDaoSupport.java:292) ~[solarnet-common-1.3.5.jar:1.3.5]
          at net.solarnetwork.central.dao.mybatis.support.BaseMyBatisGenericDaoSupport.save(BaseMyBatisGenericDaoSupport.java:163) ~[solarnet-common-1.3.5.jar:1.3.5]
          at net.solarnetwork.central.dao.mybatis.support.BaseMyBatisGenericDaoSupport$$FastClassBySpringCGLIB$$9036fad1.invoke(<generated>) ~[solarnet-common-1.3.5.jar:1.3.5]
          at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) ~[spring-core-5.3.16.jar:5.3.16]
          at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:783) ~[spring-aop-5.3.16.jar:5.3.16]
          at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.3.16.jar:5.3.16]
          at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753) ~[spring-aop-5.3.16.jar:5.3.16]
          at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123) ~[spring-tx-5.3.16.jar:5.3.16]
          at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388) ~[spring-tx-5.3.16.jar:5.3.16]
          at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119) ~[spring-tx-5.3.16.jar:5.3.16]
          at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.16.jar:5.3.16]
          at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753) ~[spring-aop-5.3.16.jar:5.3.16]
          at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:698) ~[spring-aop-5.3.16.jar:5.3.16]
          at net.solarnetwork.central.ocpp.dao.mybatis.MyBatisCentralChargePointDao$$EnhancerBySpringCGLIB$$50261e0f.save(<generated>) ~[solarnet-ocpp-1.0.0.jar:1.0.0]
          at net.solarnetwork.central.user.ocpp.biz.dao.DaoUserOcppBiz.saveChargePoint(DaoUserOcppBiz.java:246) ~[solarnet-user-ocpp-1.0.0.jar:1.0.0]
          at net.solarnetwork.central.user.ocpp.biz.dao.DaoUserOcppBiz$$FastClassBySpringCGLIB$$a5319b19.invoke(<generated>) ~[solarnet-user-ocpp-1.0.0.jar:1.0.0]
          at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) ~[spring-core-5.3.16.jar:5.3.16]
          at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:783) ~[spring-aop-5.3.16.jar:5.3.16]
          at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.3.16.jar:5.3.16]
          at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753) ~[spring-aop-5.3.16.jar:5.3.16]
          at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:58) ~[spring-aop-5.3.16.jar:5.3.16]
          at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:175) ~[spring-aop-5.3.16.jar:5.3.16]
          at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753) ~[spring-aop-5.3.16.jar:5.3.16]
          at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:58) ~[spring-aop-5.3.16.jar:5.3.16]
          at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:175) ~[spring-aop-5.3.16.jar:5.3.16]
          at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753) ~[spring-aop-5.3.16.jar:5.3.16]
          at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123) ~[spring-tx-5.3.16.jar:5.3.16]
          at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388) ~[spring-tx-5.3.16.jar:5.3.16]
          at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119) ~[spring-tx-5.3.16.jar:5.3.16]
          at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.16.jar:5.3.16]
          at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753) ~[spring-aop-5.3.16.jar:5.3.16]
          at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97) ~[spring-aop-5.3.16.jar:5.3.16]
          at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.16.jar:5.3.16]
          at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753) ~[spring-aop-5.3.16.jar:5.3.16]
          at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:698) ~[spring-aop-5.3.16.jar:5.3.16]
          at net.solarnetwork.central.user.ocpp.biz.dao.DaoUserOcppBiz$$EnhancerBySpringCGLIB$$16f122b5.saveChargePoint(<generated>) ~[solarnet-user-ocpp-1.0.0.jar:1.0.0]
          at net.solarnetwork.central.reg.web.api.v1.UserOcppController.saveChargePoint(UserOcppController.java:182) ~[classes/:na]
      

            Assignee:
            Matt Magoffin
            Reporter:
            Matt Magoffin
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved: