首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Java 數據入庫成功卻拋 NullPointerException:DAO 層 selectOne 返回值陷阱

     編輯:程式設計綜合問答

在使用 MyBatis/Spring 框架進行數據持久化時,常見現象:數據已成功寫入數據庫,但隨即拋出 java.lang.NullPointerException,堆疊指向 DAO 的 insertVideoResource 方法。這通常是因為誤用 selectOne 執行插入操作,導致返回值處理錯誤。

錯誤代碼分析

public int insertVideoResource(VideoResource vr) {
    // 錯誤:使用 selectOne 執行 INSERT 語句
    return getSqlSession().selectOne(Advertising.class.getName() + ".insertVideoResource", vr);
}

根本原因

  • selectOne 專為 查詢單條記錄 設計,期望返回結果對象(如 ID、實體)。
  • INSERT 語句在數據庫層面不返回結果集(除非配置 useGeneratedKeys/keyProperty 獲取自增 ID),MyBatis 執行 selectOne 時獲取到 null。
  • 調用方(Service/Controller)對返回值直接拆箱或調用方法(如 int id = dao.insert(...); id.toString()),觸發 NPE。

正確做法

方案一:使用 insert 方法(推薦)

public int insertVideoResource(VideoResource vr) {
    // 返回影響行數(通常為 1)
    return getSqlSession().insert(Advertising.class.getName() + ".insertVideoResource", vr);
}

方案二:需獲取自增主鍵時,配置 Mapper XML

<insert id="insertVideoResource" parameterType="VideoResource" useGeneratedKeys="true" keyProperty="id" keyColumn="id">
    INSERT INTO video_resource (aid, video_url) VALUES (#{aid}, #{videoUrl})
</insert>

Java 代碼仍用 insert(),插入後 vr.getId() 即可獲取生成的主鍵。

方案三:若必須用 selectOne(如調用存儲過程返回值)

public Integer insertVideoResource(VideoResource vr) {  // 返回 Integer 而非 int
    Object result = getSqlSession().selectOne(...);
    return result != null ? (Integer) result : 0;  // 空值保護
}

Service 層調用修正

public int addVideoResource(Advertising ad) {
    if (ad == null) return 0;
    advertisingDao.insert(ad);  // 假設此處已生成 ad.id
    VideoResource vr = new VideoResource();
    vr.setAid(ad.getId());
    vr.setVideoUrl(ad.getVideoUrl());
    return advertisingDao.insertVideoResource(vr);  // 現在返回影響行數
}

調試建議

  1. 檢查 Mapper XML 中 insert 語句的 id 是否與 DAO 調用一致。
  2. 啟用 MyBatis 日誌(log4j.logger.org.apache.ibatis=DEBUG)查看實際執行的 SQL 及返回值。
  3. 在 Service 層添加斷點,觀察 DAO 返回值類型與實際值。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved