@Repository

Spring에서 데이터 접근을 담당하는 계층 빈을 등록하는 어노테이션입니다. DB와 통신하며, 예외 변환 기능이 추가되어 있습니다.

기본 사용법

@Repository
public class UserRepository {

    @PersistenceContext
    private EntityManager em;

    public User findById(Long id) {
        return em.find(User.class, id);
    }

    public void save(User user) {
        em.persist(user);
    }

    public List<User> findAll() {
        return em.createQuery("SELECT u FROM User u", User.class)
            .getResultList();
    }
}

계층 구조에서의 위치

@Controller  ─ 요청/응답 처리
    ↓
@Service     ─ 비즈니스 로직
    ↓
@Repository  ─ DB 접근 ← 여기
    ↓
[Database]

@Repository만의 특별한 기능: 예외 변환

@Repository
public class UserRepository {

    public void save(User user) {
        // SQLException, JPA 예외 발생 시
        // → DataAccessException으로 자동 변환
    }
}
[DB별 예외]
├─ MySQL: MySQLIntegrityConstraintViolationException
├─ Oracle: OracleSQLException
├─ PostgreSQL: PSQLException
    ↓
[Spring 표준 예외]
└─ DataAccessException
   ├─ DataIntegrityViolationException
   ├─ DuplicateKeyException
   └─ EmptyResultDataAccessException

왜 예외 변환이 필요한가?

// X DB 종속적인 예외 처리
try {
    userRepository.save(user);
} catch (MySQLIntegrityConstraintViolationException e) {
    // MySQL에서만 동작
}

// O Spring 표준 예외로 처리
try {
    userRepository.save(user);
} catch (DataIntegrityViolationException e) {
    // 어떤 DB든 동작
}

@Repository vs @Component

항목@Component@Repository
빈 등록OO
예외 변환XO
용도범용데이터 접근 계층

Spring Data JPA 사용 시

// 인터페이스만 정의하면 구현체 자동 생성
public interface UserRepository extends JpaRepository<User, Long> {

    List<User> findByName(String name);

    Optional<User> findByEmail(String email);
}

실무 패턴

// 커스텀 쿼리가 필요한 경우
public interface UserRepository extends JpaRepository<User, Long> {

    @Query("SELECT u FROM User u WHERE u.status = :status")
    List<User> findActiveUsers(@Param("status") Status status);
}

// 복잡한 쿼리는 별도 구현
@Repository
@RequiredArgsConstructor
public class UserQueryRepository {

    private final JPAQueryFactory queryFactory;

    public List<UserDto> searchUsers(UserSearchCondition condition) {
        // QueryDSL 사용
    }
}

→ 어떤 예외가 발생하면 트랜잭션을 롤백하나요?

CSLOG에서 보기