1 분 소요

문제 상황

OAuth를 통한 로그인 테스트 중 발생했다. 로그인 ID를 이메일로 설정했는데 OAuth로 처음 로그인하는 경우 회원가입까지 자동으로
되도록 만들었는데 그 과정에서 메인 페이지로 넘어가지 않고 다음 에러 로그를 남겼다.

org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction
Caused by: jakarta.persistence.RollbackException: Error while committing the transaction
	at org.hibernate.internal.ExceptionConverterImpl.convertCommitException(ExceptionConverterImpl.java:65) ~[hibernate-core-6.2.5.Final.jar:6.2.5.Final]
	at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:104) ~[hibernate-core-6.2.5.Final.jar:6.2.5.Final]
	at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:561) ~[spring-orm-6.0.10.jar:6.0.10]
	... 98 common frames omitted
Caused by: jakarta.validation.ConstraintViolationException: Validation failed for classes [yeolJyeongKong.mall.domain.entity.User] during persist time for groups [jakarta.validation.groups.Default, ]
List of constraint violations:[
	ConstraintViolationImpl{interpolatedMessage='길이가 0에서 10 사이여야 합니다', propertyPath=username, rootBeanClass=class yeolJyeongKong.mall.domain.entity.User, messageTemplate='{org.hibernate.validator.constraints.Length.message}'}
	ConstraintViolationImpl{interpolatedMessage='길이가 8에서 15 사이여야 합니다', propertyPath=password, rootBeanClass=class yeolJyeongKong.mall.domain.entity.User, messageTemplate='{org.hibernate.validator.constraints.Length.message}'}
]
	at org.hibernate.boot.beanvalidation.BeanValidationEventListener.validate(BeanValidationEventListener.java:151) ~[hibernate-core-6.2.5.Final.jar:6.2.5.Final]
	at org.hibernate.boot.beanvalidation.BeanValidationEventListener.onPreInsert(BeanValidationEventListener.java:81) ~[hibernate-core-6.2.5.Final.jar:6.2.5.Final]
	at org.hibernate.action.internal.EntityInsertAction.preInsert(EntityInsertAction.java:215) ~[hibernate-core-6.2.5.Final.jar:6.2.5.Final]
	at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:98) ~[hibernate-core-6.2.5.Final.jar:6.2.5.Final]
	at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:606) ~[hibernate-core-6.2.5.Final.jar:6.2.5.Final]
	at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:475) ~[hibernate-core-6.2.5.Final.jar:6.2.5.Final]
	at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:358) ~[hibernate-core-6.2.5.Final.jar:6.2.5.Final]
	at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:39) ~[hibernate-core-6.2.5.Final.jar:6.2.5.Final]
	at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:127) ~[hibernate-core-6.2.5.Final.jar:6.2.5.Final]
	at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1412) ~[hibernate-core-6.2.5.Final.jar:6.2.5.Final]
	at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:485) ~[hibernate-core-6.2.5.Final.jar:6.2.5.Final]
	at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:2301) ~[hibernate-core-6.2.5.Final.jar:6.2.5.Final]
	at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:1966) ~[hibernate-core-6.2.5.Final.jar:6.2.5.Final]
	at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:439) ~[hibernate-core-6.2.5.Final.jar:6.2.5.Final]
	at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:169) ~[hibernate-core-6.2.5.Final.jar:6.2.5.Final]
	at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:267) ~[hibernate-core-6.2.5.Final.jar:6.2.5.Final]
	at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:101) ~[hibernate-core-6.2.5.Final.jar:6.2.5.Final]
	... 99 common frames omitted

해결 방법

로그를 보면 각 필드에 대해 validation 체크가 이뤄지는 도중 발생한 오류였는지 길이가 0에서 10 사이여야 합니다라는 메시지
가 남겨져 있다. 따로 이런 에러 메시지가 남도록 설정한 적이 없었기 때문에 각 필드에 제약조건으로 설정했던 애노테이션에 설정된
메시지라고 생각했고, 길이가 0~10, 8~15로 설정된 필드가 있는지 찾아보니 usernamepassword가 있었다.

public class User {
  ...
  @NonNull @Length(max = 10)
  private String username;

  @NonNull @Length(min = 8, max = 15)
  private String password;
  ...

  public User(String email, String password, String provider, String providerId) {
    username = email;
    this.email = email;
    this.password = password;
    ...
  }
}


usernameemail을 그대로 사용하고, password는 OAuth에서 따로 지정하지 않기 때문에 랜덤값을 받고 있었는데 모두
모두 최대 길이 제한을 넘어서 발생하는 문제였다. 그리고 passwordBCryptPasswordEncoder로 인코딩을 거친 값이 넘어
오고 있었기 때문에 길이 제한을 쉽게 넘었다. 그래서 username@앞에 적힌 ID만 받도록 하고 최대 길이 제한을 늘리고
password는 제한을 없앤 뒤 값을 저장하지 않도록 처리했다.

public class User {
  ...
  @NonNull @Length(max = 20)
  private String username;

  @NonNull
  private String password;
  ...

  public User(String email, String provider, String providerId) {
    username = email.substring(0, email.indexOf('@'));
    this.email = email;
    ...
  }
}

카테고리:

업데이트:

댓글남기기