org.mybatis.spring.MyBatisSystemException
at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:97)
at org.mybatis.spring.SqlSessionTemplateSqlSessionInterceptor.invoke([SqlSessionTemplate.java:439](command:java.test.openStackTrace?Proxy88.insert(Unknown Source)
at org.mybatis.spring.SqlSessionTemplate.insert(SqlSessionTemplate.java:272)
at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:62)
at org.apache.ibatis.binding.MapperProxyPlainMethodInvoker.invoke([MapperProxy.java:141](command:java.test.openStackTrace?Proxy128.insert(Unknown Source)
at kr.co.sonystore.mappers.TodaySaleMapperTest.insertTest(TodaySaleMapperTest.java:20)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
Caused by: org.apache.ibatis.executor.ExecutorException: Error getting generated key or setting result to parameter object. Cause: org.apache.ibatis.executor.ExecutorException: No setter found for the keyProperty 'id' in 'org.apache.ibatis.reflection.SystemMetaObjectNullObject'.
@Insert(
"<script>" +
"INSERT INTO today_sales (date, total)"+
"<choose>" +
"<when test='exists'>" +
"SELECT DATE(p.date) AS dt, SUM(p.total) AS total "+
"FROM payments p"+
"WHERE paycheck = 'Y' AND" +
"DATE(p.date) = DATE(NOW())"+
"GROUP BY dt" +
"</when>" +
"<otherwise>" +
"VALUES (DATE(NOW()), 0)" +
"</otherwise>" +
"</choose>" +
"</script>"
)
@Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id")
public int insert();
@Options 절을 주석처리 하니 에러가 나지 않았다.
===>>>
주석 처리된 @Options 어노테이션을 제거했을 때 오류가 발생하지 않는 이유는
MyBatis가 자동 생성된 키를 반환하려고 할 때 발생하는 문제를 피하기 때문이다.
@Options 어노테이션을 사용하면 MyBatis는 삽입된 레코드의 자동 생성된 키를 반환하려고 시도한다.
그러나 이 과정에서 keyProperty로 지정된 필드에 대한 setter 메서드를 찾지 못하거나, SQL 구문이 올바르지 않으면 오류가 발생할 수 있다.
키 반환 설정 문제: keyProperty로 지정된 필드에 대한 setter 메서드가 없거나, MyBatis가 해당 필드를 찾지 못할 때 오류가 발생한다.
SQL 구문 문제: INSERT INTO ... SELECT ... 구문과 INSERT INTO ... VALUES ... 구문을 혼합하여 사용할 때, MyBatis가 자동 생성된 키를 올바르게 처리하지 못할 수 있다.
✔️@Options 어노테이션을 사용하여 자동 생성된 키를 반환하려고 할 때, 동적 쿼리에서 받아오는 값이 없으면 생성된 키를 맵핑할 대상 객체(빈즈)가 없기 때문에 오류가 발생한다.
동적 쿼리에서 조건에 따라 삽입되는 데이터가 없으면, MyBatis는 자동 생성된 키를 반환할 수 없다!!!
@Options 는
매핑 구문에 부가적으로 필요한 다양한 설정을 할 수 있다.
매핑 구문의 속성을 다양하게 적으면 아무래도 보기 불편하기 때문에 @Options 어노테이션으로 별도로 정의하면 가시성이 좋다.
1. useGeneratedKeys
설명: 자동 생성된 키를 사용하도록 설정합니다.
타입: boolean
기본값: false
예시: @Options(useGeneratedKeys = true)
2.keyProperty
설명: 자동 생성된 키를 저장할 객체의 속성 이름을 지정합니다.
타입: String
기본값: 없음
예시: @Options(keyProperty = "id")
3. keyColumn
설명: 자동 생성된 키를 반환하는 데이터베이스 열 이름을 지정합니다.
타입: String
기본값: 없음
예시: @Options(keyColumn = "id")
4. flushCache
설명: 쿼리 실행 후 MyBatis의 2차 캐시를 플러시할지 여부를 설정합니다.
타입: boolean
기본값: false
예시: @Options(flushCache = true)
5. timeout
설명: 쿼리 실행 타임아웃을 설정합니다.
타입: int
기본값: 없음
예시: @Options(timeout = 30)
6. fetchSize
설명: 쿼리 실행 시 페치 크기를 설정합니다.
타입: int
기본값: 없음
예시: @Options(fetchSize = 100)
해결 : @Options 절 제거.
테이블에 레코드 추가
문법
| 기본적인 INSERT 방법
1. INSERT INTO 테이블이름(필드이름1, 필드이름2, 필드이름3, ...)
VALUES (데이터값1, 데이터값2, 데이터값3, ...)
2. INSERT INTO 테이블이름
VALUES (데이터값1, 데이터값2, 데이터값3, ...)
| 동시에 여러 행 INSERT 방법 ( SQL Server 2008부터 지원 )
3. INSERT INTO 테이블이름(필드이름1, 필드이름2)
VALUES (데이터값1, 데이터값2), (데이터값1, 데이터값2), ...
| SELECT 결과 INSERT 방법 ( Select 절을 사용하여 조회한 결과를 바로 INSERT 할 수 있다 )
4. INSERT INTO 테이블이름(필드이름1, 필드이름2)
SELECT (필드이름1, 필드이름2)
FROM 테이블이름
WHERE 절~~~~
'IT > Spring' 카테고리의 다른 글
| RestTemplate WebClient RestClient (2) | 2025.01.23 |
|---|---|
| React 프로젝트 Spring으로 가져오기 (0) | 2024.12.31 |
| Swagger (1) | 2024.12.24 |
| Mapper Error (@ResultMap) (0) | 2024.12.04 |
| @ResponseBody (0) | 2024.12.03 |