将java.lang.String类型映射到Postgres JSON类型

将java.lang.String类型映射到Postgres JSON类型,java,json,spring,postgresql,mybatis,Java,Json,Spring,Postgresql,Mybatis,我的问题与下面的问题有关,虽然在postgres中测试向psql传递字符串时答案有效,但从Java代码传递字符串时答案无效 我使用MyBatis通过Spring注入将sql映射到postgres数据库 这是我的MyBatis Java接口,我在映射到Postgres JSON列时遇到问题的方法是updateState()方法 以下是我的applicationContext.xml文件的代码 <?xml version="1.0" encoding="UTF-8"?> <bean

我的问题与下面的问题有关,虽然在postgres中测试向psql传递字符串时答案有效,但从Java代码传递字符串时答案无效

我使用MyBatis通过Spring注入将sql映射到postgres数据库

这是我的MyBatis Java接口,我在映射到Postgres JSON列时遇到问题的方法是updateState()方法

以下是我的applicationContext.xml文件的代码

<?xml version="1.0" encoding="UTF-8"?>
<beans
    xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans     http://www.springframework.org/schema/beans/spring-beans.xsd"
     default-lazy-init="false">

    <bean id="configurer"
        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <list merge="true">
                <value>classpath:db.properties</value>
            </list>
        </property>
    </bean>

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="org.postgresql.Driver" />
        <property name="url" value="${test.db.url}" />
        <property name="username" value="${test.db.username}" />
        <property name="password" value="${test.db.password}" />
    </bean>

    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="configLocation" value="classpath:mybatis-config.xml" />
        <property name="dataSource" ref="dataSource" />
    </bean>

    <bean id="spokeDAOMyBatis" class="org.mybatis.spring.mapper.MapperFactoryBean">
        <property name="mapperInterface" value="receiver.spoke.SpokeDAOMyBatis" />
        <property name="sqlSessionFactory" ref="sqlSessionFactory" />
    </bean>

</beans>
以下是mybatis-config.xml文件

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>
    <settings>
        <setting name="cacheEnabled" value="false" />
        <setting name="lazyLoadingEnabled" value="false" />
        <setting name="defaultExecutorType" value="REUSE" />
        <!-- <setting name="defaultStatementTimeout" value="20000" /> -->
        <setting name="logImpl" value="LOG4J" />
    </settings>
</configuration>
下一个用于字符串到json转换的创建函数

CREATE OR REPLACE FUNCTION json_intext(text) RETURNS json AS $$
SELECT json_in($1::cstring); 
$$ LANGUAGE SQL IMMUTABLE;
CREATE FUNCTION
创建演员阵容

CREATE CAST (text AS json) WITH FUNCTION json_intext(text) AS IMPLICIT;
CREATE CAST
当从我的psql中进行转换时,这是有效的,但不是从java端

以下是一些测试,显示了函数和强制转换通过psql为一个名为xxx的表工作,以及不接受无效json的事实

PREPARE test(text) AS INSERT INTO xxx(id,state) VALUES (1,$1);
PREPARE
execute test('{}');
INSERT 0 1
select json_in('a');
ERROR:  invalid input syntax for type json
DETAIL:  Token "a" is invalid.
CONTEXT:  JSON data, line 1: a
select json_in('a'::cstring);
ERROR:  invalid input syntax for type json
DETAIL:  Token "a" is invalid.
CONTEXT:  JSON data, line 1: a
select json_in('{}');
 json_in 
---------
 {}
(1 row)

select json_in('{');
ERROR:  invalid input syntax for type json
DETAIL:  The input string ended unexpectedly.
CONTEXT:  JSON data, line 1: {
select json_in('{}');
 json_in 
 ---------
  {}
(1 row)
以下是我的测试课程:

package receiver.spoke;

import static org.junit.Assert.*;

import java.sql.SQLException;
import java.util.List;

import org.apache.commons.dbcp.BasicDataSource;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import receiver.bean.Spoke;
import receiver.spoke.SpokeDAOMyBatis;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "/applicationContext.xml" })
public class SpokeDAOMyBatisTest {

    @Autowired 
    @Qualifier("spokeDAOMyBatis")
    private SpokeDAOMyBatis spokeDAOMyBatis;

    @Autowired
    @Qualifier("dataSource")
    private BasicDataSource datasource;

    @Before
    public void connectionTest() throws SQLException {     
        datasource.getConnection();
    }

    @Test
    public void updateState() {

        assertNotNull(spokeDAOMyBatis);
        spokeDAOMyBatis.updateState(1L, "{}");
        assertTrue("Returned wrong state", spokeDAOMyBatis.getState(1L).equals("{}"));
    }

    @Test
    public void getState() {

        assertNotNull(spokeDAOMyBatis);
        String str1 = spokeDAOMyBatis.getState(1L);
        String str2 = spokeDAOMyBatis.getState(2L);
        assertTrue("Returned wrong state", spokeDAOMyBatis.getState(1L).equals(str1));
        assertTrue("Returned wrong state", spokeDAOMyBatis.getState(2L).equals(str2));
    }

    @Test
    public void getAllSpokesTest() {

        assertNotNull(spokeDAOMyBatis);
        List<Spoke> list = spokeDAOMyBatis.getSpokes();
        System.out.println(list.toString());

        assertNotNull("List of spokes returned null", list);
        assertTrue("List of spokes is empty", !list.isEmpty());
        assertNotNull("Invalid spoke", list.get(0));
        assertNotNull("id not loaded", list.get(0).getId());
        assertNotNull("description not loaded", list.get(0).getDescription());
        assertNotNull("uri not loaded", list.get(0).getUri());
        assertNotNull("updatets not loaded", list.get(0).getUpdatets());
    }    
}
package receiver.spoke;
导入静态org.junit.Assert.*;
导入java.sql.SQLException;
导入java.util.List;
导入org.apache.commons.dbcp.BasicDataSource;
导入org.junit.Before;
导入org.junit.Test;
导入org.junit.runner.RunWith;
导入org.springframework.beans.factory.annotation.Autowired;
导入org.springframework.beans.factory.annotation.Qualifier;
导入org.springframework.test.context.ContextConfiguration;
导入org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
导入receiver.bean.Spoke;
导入receiver.SpokeDAOMyBatis;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(位置={“/applicationContext.xml”})
公共类SpokedaoMybatist{
@自动连线
@限定词(“spokeDAOMyBatis”)
私人SpokeDAOMyBatis SpokeDAOMyBatis;
@自动连线
@限定符(“数据源”)
私有源数据源;
@以前
public void connectionTest()引发SQLException{
datasource.getConnection();
}
@试验
公共屋({
assertNotNull(spokeDAOMyBatis);
spokeDAOMyBatis.updateState(1L,“{}”);
assertTrue(“返回了错误的状态”,spokeDAOMyBatis.getState(1L).equals(“{}”);
}
@试验
public void getState(){
assertNotNull(spokeDAOMyBatis);
字符串str1=spokeDAOMyBatis.getState(1L);
字符串str2=spokeDAOMyBatis.getState(2L);
assertTrue(“返回错误状态”,spokeDAOMyBatis.getState(1L).equals(str1));
assertTrue(“返回了错误的状态”,spokeDAOMyBatis.getState(2L).equals(str2));
}
@试验
public void getAllSpokesTest(){
assertNotNull(spokeDAOMyBatis);
List List=spokeDAOMyBatis.getSpokes();
System.out.println(list.toString());
assertNotNull(“返回null的辐条列表”,列表);
assertTrue(“辐条列表为空,!List.isEmpty());
assertNotNull(“无效发言”,list.get(0));
assertNotNull(“id未加载”,list.get(0.getId());
assertNotNull(“说明未加载”,list.get(0.getDescription());
assertNotNull(“uri未加载”,list.get(0.getUri());
assertNotNull(“未加载更新集”,list.get(0.getUpdatets());
}    
}
因此,这一切似乎都很好,但当我尝试运行Java端时,我得到了如下堆栈跟踪所示的强制转换异常:

Tests run: 3, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.241 sec <<< FAILURE!
updateState(receiver.spoke.SpokeDAOMyBatisTest)  Time elapsed: 0.035 sec  <<< ERROR!
org.springframework.jdbc.BadSqlGrammarException: 
### Error updating database.  Cause: org.postgresql.util.PSQLException: ERROR: column "state" is of type json but expression is of type character varying
  Hint: You will need to rewrite or cast the expression.
  Position: 38
### The error may involve defaultParameterMap
### The error occurred while setting parameters
### SQL: UPDATE     spokes    SET     state = ?    WHERE     id = ?
### Cause: org.postgresql.util.PSQLException: ERROR: column "state" is of type json but expression is of type character varying
  Hint: You will need to rewrite or cast the expression.
  Position: 38
; bad SQL grammar []; nested exception is org.postgresql.util.PSQLException: ERROR: column "state" is of type json but expression is of type character varying
  Hint: You will need to rewrite or cast the expression.
  Position: 38
    at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.java:231)
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:73)
    at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:74)
    at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:399)
    at com.sun.proxy.$Proxy17.update(Unknown Source)
    at org.mybatis.spring.SqlSessionTemplate.update(SqlSessionTemplate.java:269)
    at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:55)
    at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:53)
    at com.sun.proxy.$Proxy24.updateState(Unknown Source)
    at receiver.spoke.SpokeDAOMyBatisTest.updateState(SpokeDAOMyBatisTest.java:41)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:254)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:89)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:193)
    at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:252)
    at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:141)
    at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:112)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189)
    at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165)
    at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85)
    at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115)
    at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75)
Caused by: org.postgresql.util.PSQLException: ERROR: column "state" is of type json but expression is of type character varying
  Hint: You will need to rewrite or cast the expression.
  Position: 38
    at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2270)
    at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1998)
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:255)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:570)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:420)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:413)
    at org.apache.commons.dbcp.DelegatingPreparedStatement.execute(DelegatingPreparedStatement.java:169)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.apache.ibatis.logging.jdbc.PreparedStatementLogger.invoke(PreparedStatementLogger.java:59)
    at com.sun.proxy.$Proxy23.execute(Unknown Source)
    at org.apache.ibatis.executor.statement.PreparedStatementHandler.update(PreparedStatementHandler.java:45)
    at org.apache.ibatis.executor.statement.RoutingStatementHandler.update(RoutingStatementHandler.java:73)
    at org.apache.ibatis.executor.ReuseExecutor.doUpdate(ReuseExecutor.java:51)
    at org.apache.ibatis.executor.BaseExecutor.update(BaseExecutor.java:115)
    at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:170)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:386)
    ... 42 more

3601 [Thread-0] INFO  org.springframework.context.support.GenericApplicationContext - Closing org.springframework.context.support.GenericApplicationContext@4fcd19b3: startup date [Mon Jan 11 11:10:54 GMT 2016]; root of context hierarchy

测试运行:3,失败:0,错误:1,跳过:0,运行时间:0.241秒将stringtype=unspecified添加到我的jdbc连接字符串中,如建议的那样:

jdbc:postgresql://localhost:5432/dbname?stringtype=unspecified
这样做还可以删除该函数并将其从字符串转换为json

我还通过向json列传递无效json来测试更改


正如我所希望的那样,当我这样做时,我得到了一个DataIntegrityViolationException,正如我从该测试中所期望的那样

为了通过Mybatis将JSON映射到Postgresql或从Postgresql映射JSON,您应该有适当的类型处理程序

令人惊讶的是,我这里真的有一个

在添加最新版本的工件之后,您应该向代码中添加适当的处理程序

<!-- mybatis-config.xml -->
<typeHandlers>
  <package name="com.github.jneat.mybatis"/>
</typeHandlers>

在此之后,您将能够通过TreeNode接口或JsonNodeValue包装类使用JSON


请记住,在插入(和一些选择)期间,JSON应该作为字符串通过JDBC驱动程序传递。然后,您应该使用类似于
(${string_json})的语法将其转换为适当的类型::jsonb

这可能会对您有所帮助,我不想在java端将我的代码与Postgres耦合。您可以尝试绑定
json
类型,或者您可以向jdbc连接字符串添加(然后PostgreSQL将猜测这些参数的类型)。您好,我尝试按照上面的建议添加状态,但仍然存在相同的错误。将stringtype=unspecified添加到我的jdbc连接字符串中就成功了。这似乎是一种解决方法,而不是最佳做法。
PREPARE test(text) AS INSERT INTO xxx(id,state) VALUES (1,$1);
PREPARE
execute test('{}');
INSERT 0 1
select json_in('a');
ERROR:  invalid input syntax for type json
DETAIL:  Token "a" is invalid.
CONTEXT:  JSON data, line 1: a
select json_in('a'::cstring);
ERROR:  invalid input syntax for type json
DETAIL:  Token "a" is invalid.
CONTEXT:  JSON data, line 1: a
select json_in('{}');
 json_in 
---------
 {}
(1 row)

select json_in('{');
ERROR:  invalid input syntax for type json
DETAIL:  The input string ended unexpectedly.
CONTEXT:  JSON data, line 1: {
select json_in('{}');
 json_in 
 ---------
  {}
(1 row)
package receiver.spoke;

import static org.junit.Assert.*;

import java.sql.SQLException;
import java.util.List;

import org.apache.commons.dbcp.BasicDataSource;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import receiver.bean.Spoke;
import receiver.spoke.SpokeDAOMyBatis;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "/applicationContext.xml" })
public class SpokeDAOMyBatisTest {

    @Autowired 
    @Qualifier("spokeDAOMyBatis")
    private SpokeDAOMyBatis spokeDAOMyBatis;

    @Autowired
    @Qualifier("dataSource")
    private BasicDataSource datasource;

    @Before
    public void connectionTest() throws SQLException {     
        datasource.getConnection();
    }

    @Test
    public void updateState() {

        assertNotNull(spokeDAOMyBatis);
        spokeDAOMyBatis.updateState(1L, "{}");
        assertTrue("Returned wrong state", spokeDAOMyBatis.getState(1L).equals("{}"));
    }

    @Test
    public void getState() {

        assertNotNull(spokeDAOMyBatis);
        String str1 = spokeDAOMyBatis.getState(1L);
        String str2 = spokeDAOMyBatis.getState(2L);
        assertTrue("Returned wrong state", spokeDAOMyBatis.getState(1L).equals(str1));
        assertTrue("Returned wrong state", spokeDAOMyBatis.getState(2L).equals(str2));
    }

    @Test
    public void getAllSpokesTest() {

        assertNotNull(spokeDAOMyBatis);
        List<Spoke> list = spokeDAOMyBatis.getSpokes();
        System.out.println(list.toString());

        assertNotNull("List of spokes returned null", list);
        assertTrue("List of spokes is empty", !list.isEmpty());
        assertNotNull("Invalid spoke", list.get(0));
        assertNotNull("id not loaded", list.get(0).getId());
        assertNotNull("description not loaded", list.get(0).getDescription());
        assertNotNull("uri not loaded", list.get(0).getUri());
        assertNotNull("updatets not loaded", list.get(0).getUpdatets());
    }    
}
Tests run: 3, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.241 sec <<< FAILURE!
updateState(receiver.spoke.SpokeDAOMyBatisTest)  Time elapsed: 0.035 sec  <<< ERROR!
org.springframework.jdbc.BadSqlGrammarException: 
### Error updating database.  Cause: org.postgresql.util.PSQLException: ERROR: column "state" is of type json but expression is of type character varying
  Hint: You will need to rewrite or cast the expression.
  Position: 38
### The error may involve defaultParameterMap
### The error occurred while setting parameters
### SQL: UPDATE     spokes    SET     state = ?    WHERE     id = ?
### Cause: org.postgresql.util.PSQLException: ERROR: column "state" is of type json but expression is of type character varying
  Hint: You will need to rewrite or cast the expression.
  Position: 38
; bad SQL grammar []; nested exception is org.postgresql.util.PSQLException: ERROR: column "state" is of type json but expression is of type character varying
  Hint: You will need to rewrite or cast the expression.
  Position: 38
    at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.java:231)
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:73)
    at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:74)
    at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:399)
    at com.sun.proxy.$Proxy17.update(Unknown Source)
    at org.mybatis.spring.SqlSessionTemplate.update(SqlSessionTemplate.java:269)
    at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:55)
    at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:53)
    at com.sun.proxy.$Proxy24.updateState(Unknown Source)
    at receiver.spoke.SpokeDAOMyBatisTest.updateState(SpokeDAOMyBatisTest.java:41)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:254)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:89)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:193)
    at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:252)
    at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:141)
    at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:112)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189)
    at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165)
    at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85)
    at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115)
    at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75)
Caused by: org.postgresql.util.PSQLException: ERROR: column "state" is of type json but expression is of type character varying
  Hint: You will need to rewrite or cast the expression.
  Position: 38
    at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2270)
    at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1998)
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:255)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:570)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:420)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:413)
    at org.apache.commons.dbcp.DelegatingPreparedStatement.execute(DelegatingPreparedStatement.java:169)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.apache.ibatis.logging.jdbc.PreparedStatementLogger.invoke(PreparedStatementLogger.java:59)
    at com.sun.proxy.$Proxy23.execute(Unknown Source)
    at org.apache.ibatis.executor.statement.PreparedStatementHandler.update(PreparedStatementHandler.java:45)
    at org.apache.ibatis.executor.statement.RoutingStatementHandler.update(RoutingStatementHandler.java:73)
    at org.apache.ibatis.executor.ReuseExecutor.doUpdate(ReuseExecutor.java:51)
    at org.apache.ibatis.executor.BaseExecutor.update(BaseExecutor.java:115)
    at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:170)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:386)
    ... 42 more

3601 [Thread-0] INFO  org.springframework.context.support.GenericApplicationContext - Closing org.springframework.context.support.GenericApplicationContext@4fcd19b3: startup date [Mon Jan 11 11:10:54 GMT 2016]; root of context hierarchy
jdbc:postgresql://localhost:5432/dbname?stringtype=unspecified
<!-- mybatis-config.xml -->
<typeHandlers>
  <package name="com.github.jneat.mybatis"/>
</typeHandlers>