插入null时MyBatis nullPointerException

时间:2014-12-12 00:36:11

标签: java spring mybatis

当我尝试使用空主键插入记录然后获取键值(oracle触发器设置键)时,我得到MyBatis NPE。

FooMapper界面:

...
public void insertFooObject (final Foo foo);
...

FooMapper.xml:

...
    <insert id="insertFooObject" useGeneratedKeys="true" keyColumn="foo_id" keyProperty="fooId">
        insert into foos (foo_id, gcor_id, registration_date)
        values (#{fooId, jdbcType=NUMERIC}, #{gcorId, jdbcType=NUMERIC}, #{registrationDate, jdbcType=DATE})
    </insert>  
...

这是模特:

public class Foo {
    private final Integer fooId;
    private final Integer gcorId;
    private final Date registrationDate;

    public Foo(final Integer fooId, final Integer gcorId, final Date registrationDate)     {
        this.fooId = fooId;
        this.gcorId = gcorId;
        this.registrationDate = registrationDate;
    }
...

这就是电话:

... 
Foo foo = new Foo(null, 229, null);
fooMapper.insertFooObject(foo);
...

fooMapper是spring注入的,可以成功用于其他SQL语句。当我为fooId传入一个数字并且registrationDate为null时,一切正常。当fooId为null(如图所示)时,我收到错误:

org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.PersistenceException: 
 Error updating database.  Cause: java.lang.NullPointerException
 The error may involve defaultParameterMap
 The error occurred while setting parameters
 SQL: insert into foos (foo_id, gcor_id, registration_date)         values (?, ?, ?)
 Cause: java.lang.NullPointerException

这是我的配置文件:

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

    <bean id="datasource" class="org.apache.ibatis.datasource.pooled.PooledDataSource">
        <property name="driver" value="oracle.jdbc.driver.OracleDriver"/>        
        <property name="url" value="jdbc:oracle:thin:@......"/>
        <property name="username" value="..."/>
        <property name="password" value="..."/>
    </bean>

    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="datasource"/>
    </bean>

    <bean id="fooMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
        <property name="mapperInterface" value="com.foo.FooMapper" />
        <property name="sqlSessionFactory" ref="sqlSessionFactory" />
    </bean>

    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="datasource" />
    </bean>
</beans>

任何想法如何纠正这个?我没有运气谷歌搜索,并认为通过指定jdbcType我可以。谢谢!

2 个答案:

答案 0 :(得分:1)

我相信你正在使用useGeneratedkeys用于oracle,而oracle并不支持。我相信GeneratedKeys是由mysql和postgress支持的。而是使用selectkeys来获取下一个值,或者您可以将空值传递给fooId删除useGeneratedKeys,默认情况下为false。您可以使用序列

获取下一个值
<selectKey keyProperty="fooId"
             resultClass="int">
    SELECT nextVal('foo_id_seq')
 </selectKey>

答案 1 :(得分:0)

我在模型类(Foo.java)中发现了我的问题:

public int getFooId() {
    return fooId;
}

fooId是一个Integer而不是int。通过将getter返回类型更改为Integer,我能够插入一个空主键并获取触发器创建的序列ID