業務チェック処理を実装

リクエストパラメータの単項目/関連項目バリデーションとは別に業務的なチェック処理を追加して、エラーメッセージを返却するところまでを追加する

/src/main/java/com/example/demo/domain/mapper/UsersMapper.java

  • メールアドレスが重複するレコードが登録されているか検索するメソッドを追加
   Users lockByMailAddress(@Param("mailAddress") String mailAddress);

/src/main/resources/com/example/demo/domain/mapper/UsersMapper.xml

  • メールアドレスが重複するレコードが登録されているか検索するSQLを追加
 <select id="lockByMailAddress" resultType="com.example.demo.domain.model.Users">
        SELECT
            ID,
            MAIL_ADDRESS,
            USER_NAME,
            PASSWORD,
            LAST_LOGIN_TIME,
            REGIST_TIME,
            UPDATE_TIME,
            DELETED
        FROM
            t_users
        WHERE
            MAIL_ADDRESS = #{mailAddress} AND
            DELETED = 0
        FOR UPDATE
    </select>

/src/main/java/com/example/demo/domain/repository/UsersRepository.java

  • メールアドレスが重複するレコードが登録されているか検索するメソッドを追加
   public Users lockByMailAddress(String mailAddress) {
        return usersMapper.lockByMailAddress(mailAddress);
    }

/src/main/java/com/example/demo/service/UsersService.java

  • メールアドレスが重複するレコードが存在した場合は処理を中断し、業務例外をthrow
   @Transactional(readOnly = false)
    public UserDto create(UserDto dto) {
        
        Users duplicated = usersRepository.lockByMailAddress(dto.getMailAddress());
        if (duplicated != null) {
            throw new BusinessException("errors.users.mailAddress.duplicated", dto.getMailAddress());
        }
        
        final Users users = Users.builder()
                .mailAddress(dto.getMailAddress())
                .userName(dto.getUserName())
                .password(dto.getPassword())
                .registTime(DateUtils.getThreadDateTime())
                .updateTime(DateUtils.getThreadDateTime())
                .deleted(0)
                .build();
        usersRepository.create(users);
        LOGGER.info("#users : {}", users);
        return convert(users);
    }

/src/main/java/com/example/demo/common/utils/SystemException.java

package com.example.demo.common.utils;

import lombok.Getter;

@Getter
public class SystemException extends RuntimeException {

    /**
    * SerialVersionUID.
    */
    private static final long serialVersionUID = -8269072520808618210L;

    private String code;
    private Exception nested;

    public SystemException(String code, Exception nested) {
        super();
        this.code = code;
        this.nested = nested;
    }

    public SystemException(String code) {
        super();
        this.code = code;
    }

}

/src/main/java/com/example/demo/common/utils/BusinessException.java

package com.example.demo.common.utils;

import java.util.List;

import com.google.common.collect.Lists;

import lombok.AllArgsConstructor;
import lombok.Getter;

@Getter
public class BusinessException extends RuntimeException {

    /**
    * SerialVersionUID.
    */
    private static final long serialVersionUID = -2911618850319099751L;

    private List<ErrorInfo> errors = Lists.newArrayList();

    public BusinessException(String code) {
        this(code, new Object[0]);
    }

    public BusinessException(String code, Object... params) {
        super();
        final ErrorInfo error = new ErrorInfo(code, params);
        errors.add(error);
    }

    @Getter
    @AllArgsConstructor
    public static class ErrorInfo {
        private String code;
        private Object[] params = new Object[0];
    }
}

/src/main/java/com/example/demo/web/controller/ExceptionController.java

   @ExceptionHandler(BusinessException.class)
    public ResponseEntity<ErrorResponse> handleBusinessException(BusinessException e) {
        final List<ErrorResponse.Error> errors = Lists.newArrayList();
        final List<ErrorInfo> errorInfoList = e.getErrors();
        for (ErrorInfo errorInfo : errorInfoList) {
            errors.add(new ErrorResponse.Error(null,
                    messageSource.getMessage(errorInfo.getCode(), errorInfo.getParams(), Locale.getDefault())));
        }
        return new ResponseEntity<>(new ErrorResponse(errors), HttpStatus.BAD_REQUEST);
    }

    @ExceptionHandler(SystemException.class)
    public ResponseEntity<ErrorResponse> handleSystemException(SystemException e) {
        String errMessage = "system error happend.";
        if (e.getCode() != null) {
            errMessage = messageSource.getMessage(e.getCode(), new Object[0], Locale.getDefault());
        }
        LOGGER.error(errMessage, e);
        ErrorResponse.Error error = new ErrorResponse.Error(null, errMessage);
        return new ResponseEntity<>(new ErrorResponse(error), HttpStatus.INTERNAL_SERVER_ERROR);
    }

/src/main/resources/ValidationMessages.properties

errors.users.mailAddress.duplicated=そのメールアドレス({0})は既に登録されています