강의 신청 시 해당 강의에 수강 인원이 30명일 때 40명이 동시에 강의를 신청하는 상황에서 낙관적 락을 사용해 동시성 문제를 해결하는 테스트 코드를 작성하였다.

해당 로직처럼 for 문을 통해 JAVA 에서 제공하는 finalI 값의 id를 가진 user 객체를 생성한 후 user 객체에서 apply 메서드 매개변수로 주게 된다면

"존재하지 않는 사용자입니다." custom exception 이 발생했다.
User 클래스에서 userId가 객체가 생성될 때 id값을 자동으로 부여하는 어노테이션을 사용했는데
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long userId;
이것이 문제가 되었다.
@GeneratedValue(strategy = GenerationType.IDENTITY)는 id 생성을 위해 hibernate_sequence 테이블의 시퀀스 값을 가져와 업데이트를 하고, 그 값을 통해 id를 생성해 insert 쿼리를 사용한다.
ex) Hibernate; select "next_val" <-- 이놈
즉 ID는 hibernate에서 관리를 해준다.
User user = new User(finalI, "유저"+finalI1);
finalI 는 Java For문을 통해 제공받는 값인데 해당 객체가 저장이 될 때 sequence 테이블의 시퀀스 값을 id 값을 설정 finalI와 저장된 saveUser 객체는 다르게 나올 수 밖에 없는 것이다.

그래서 강의 신청할 때 java에서 제공하는 id값을 가져와 DB에서 찾아보니 "없는데?" 가 나오는 것이다.
또한
create table user (
user_id bigint generated by default as identity,
name varchar(10)
)
유저 객체를 생성할 때 해당 쿼리가 나오는데 이는 개발자가 수동으로 값을 지정하지 않아도 데이터베이스가 알아서 그 필드에 값을 할당한다는 뜻이다.

for문을 받은 id값으로 만들어진 user 객체에서가 아닌 저장된 후 받환받는 값으로 apply 메서드의 매개변수로 넣어주니 custom 에러가 발생되지 않았다.
user.getId() 가 아닌 -> saveUser.getId().
id 생성을 위해 hibernate_sequence 테이블의 시퀀스 값을 가져와 그 값으로 id를 생성한다는 것을 전혀 모르고 있었다.
그냥 @GeneratedValue(strategy = GenerationType.IDENTITY) 를 사용함으로 id값 자동으로 올라가니 편하네? 정도로만 알고 사용했으니...
JPA가 너무 어렵다.
그리고 과제를 해야하는 상황에서도 계속 도와주고 해결해주신 팀원들께 너무 감사하다.
팀원들 없었으면 그냥 포기하고 기능개발이나 했을듯...
양준혁님, 정한슬님 다시한번 감사드립니다.
어디서 많이 본 오류네요 ^ㅁ^ 고생 많으셨습니다! 정리하는 모습 멋집니다.