init spotless 적용

This commit is contained in:
2026-02-02 15:48:23 +09:00
parent 495ef7d86c
commit a1ffad1c4e
153 changed files with 12870 additions and 12931 deletions

View File

@@ -1,22 +1,22 @@
package com.kamco.cd.training.postgres;
import jakarta.persistence.Column;
import jakarta.persistence.MappedSuperclass;
import jakarta.persistence.PrePersist;
import java.time.ZonedDateTime;
import lombok.Getter;
import org.springframework.data.annotation.CreatedDate;
@Getter
@MappedSuperclass
public class CommonCreateEntity {
@CreatedDate
@Column(name = "created_dttm", updatable = false, nullable = false)
private ZonedDateTime createdDate;
@PrePersist
protected void onPersist() {
this.createdDate = ZonedDateTime.now();
}
}
package com.kamco.cd.training.postgres;
import jakarta.persistence.Column;
import jakarta.persistence.MappedSuperclass;
import jakarta.persistence.PrePersist;
import java.time.ZonedDateTime;
import lombok.Getter;
import org.springframework.data.annotation.CreatedDate;
@Getter
@MappedSuperclass
public class CommonCreateEntity {
@CreatedDate
@Column(name = "created_dttm", updatable = false, nullable = false)
private ZonedDateTime createdDate;
@PrePersist
protected void onPersist() {
this.createdDate = ZonedDateTime.now();
}
}

View File

@@ -1,34 +1,34 @@
package com.kamco.cd.training.postgres;
import jakarta.persistence.Column;
import jakarta.persistence.MappedSuperclass;
import jakarta.persistence.PrePersist;
import jakarta.persistence.PreUpdate;
import java.time.ZonedDateTime;
import lombok.Getter;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
@Getter
@MappedSuperclass
public class CommonDateEntity {
@CreatedDate
@Column(name = "created_dttm", updatable = false, nullable = false)
private ZonedDateTime createdDate;
@LastModifiedDate
@Column(name = "updated_dttm", nullable = false)
private ZonedDateTime modifiedDate;
@PrePersist
protected void onPersist() {
this.createdDate = ZonedDateTime.now();
this.modifiedDate = ZonedDateTime.now();
}
@PreUpdate
protected void onUpdate() {
this.modifiedDate = ZonedDateTime.now();
}
}
package com.kamco.cd.training.postgres;
import jakarta.persistence.Column;
import jakarta.persistence.MappedSuperclass;
import jakarta.persistence.PrePersist;
import jakarta.persistence.PreUpdate;
import java.time.ZonedDateTime;
import lombok.Getter;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
@Getter
@MappedSuperclass
public class CommonDateEntity {
@CreatedDate
@Column(name = "created_dttm", updatable = false, nullable = false)
private ZonedDateTime createdDate;
@LastModifiedDate
@Column(name = "updated_dttm", nullable = false)
private ZonedDateTime modifiedDate;
@PrePersist
protected void onPersist() {
this.createdDate = ZonedDateTime.now();
this.modifiedDate = ZonedDateTime.now();
}
@PreUpdate
protected void onUpdate() {
this.modifiedDate = ZonedDateTime.now();
}
}

View File

@@ -1,19 +1,19 @@
package com.kamco.cd.training.postgres;
import com.querydsl.jpa.impl.JPAQueryFactory;
import jakarta.persistence.EntityManager;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@RequiredArgsConstructor
@Configuration
public class QueryDslConfig {
private final EntityManager entityManager;
@Bean
public JPAQueryFactory jpaQueryFactory() {
return new JPAQueryFactory(entityManager);
}
}
package com.kamco.cd.training.postgres;
import com.querydsl.jpa.impl.JPAQueryFactory;
import jakarta.persistence.EntityManager;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@RequiredArgsConstructor
@Configuration
public class QueryDslConfig {
private final EntityManager entityManager;
@Bean
public JPAQueryFactory jpaQueryFactory() {
return new JPAQueryFactory(entityManager);
}
}

View File

@@ -1,30 +1,30 @@
package com.kamco.cd.training.postgres;
import com.querydsl.core.types.Order;
import com.querydsl.core.types.OrderSpecifier;
import com.querydsl.core.types.dsl.PathBuilder;
import org.springframework.data.domain.Pageable;
public class QuerydslOrderUtil {
/**
* Pageable의 Sort 정보를 QueryDSL OrderSpecifier 배열로 변환
*
* @param pageable Spring Pageable
* @param entityClass 엔티티 클래스 (예: User.class)
* @param alias Q 엔티티 alias (예: "user")
*/
public static <T> OrderSpecifier<?>[] getOrderSpecifiers(
Pageable pageable, Class<T> entityClass, String alias) {
PathBuilder<T> entityPath = new PathBuilder<>(entityClass, alias);
return pageable.getSort().stream()
.map(
sort -> {
Order order = sort.isAscending() ? Order.ASC : Order.DESC;
// PathBuilder.get()는 컬럼명(String)을 동적 Path로 반환
return new OrderSpecifier<>(
order, entityPath.get(sort.getProperty(), Comparable.class));
})
.toArray(OrderSpecifier[]::new);
}
}
package com.kamco.cd.training.postgres;
import com.querydsl.core.types.Order;
import com.querydsl.core.types.OrderSpecifier;
import com.querydsl.core.types.dsl.PathBuilder;
import org.springframework.data.domain.Pageable;
public class QuerydslOrderUtil {
/**
* Pageable의 Sort 정보를 QueryDSL OrderSpecifier 배열로 변환
*
* @param pageable Spring Pageable
* @param entityClass 엔티티 클래스 (예: User.class)
* @param alias Q 엔티티 alias (예: "user")
*/
public static <T> OrderSpecifier<?>[] getOrderSpecifiers(
Pageable pageable, Class<T> entityClass, String alias) {
PathBuilder<T> entityPath = new PathBuilder<>(entityClass, alias);
return pageable.getSort().stream()
.map(
sort -> {
Order order = sort.isAscending() ? Order.ASC : Order.DESC;
// PathBuilder.get()는 컬럼명(String)을 동적 Path로 반환
return new OrderSpecifier<>(
order, entityPath.get(sort.getProperty(), Comparable.class));
})
.toArray(OrderSpecifier[]::new);
}
}

View File

@@ -1,77 +1,77 @@
// package com.kamco.cd.kamcoback.postgres.core;
//
// import com.kamco.cd.kamcoback.common.service.BaseCoreService;
// import com.kamco.cd.kamcoback.postgres.entity.AnimalEntity;
// import com.kamco.cd.kamcoback.postgres.entity.ZooEntity;
// import com.kamco.cd.kamcoback.postgres.repository.AnimalRepository;
// import com.kamco.cd.kamcoback.postgres.repository.ZooRepository;
// import com.kamco.cd.kamcoback.zoo.dto.AnimalDto;
// import jakarta.persistence.EntityNotFoundException;
// import lombok.RequiredArgsConstructor;
// import org.springframework.data.domain.Page;
// import org.springframework.stereotype.Service;
// import org.springframework.transaction.annotation.Transactional;
//
// @Service
// @RequiredArgsConstructor
// @Transactional(readOnly = true)
// public class AnimalCoreService
// implements BaseCoreService<AnimalDto.Basic, Long, AnimalDto.SearchReq> {
//
// private final AnimalRepository animalRepository;
// private final ZooRepository zooRepository;
//
// @Transactional(readOnly = true)
// public AnimalDto.Basic getDataByUuid(String uuid) {
// AnimalEntity getZoo =
// animalRepository
// .getAnimalByUuid(uuid)
// .orElseThrow(() -> new EntityNotFoundException("Zoo not found with uuid: " + uuid));
// return getZoo.toDto();
// }
//
// // AddReq를 받는 추가 메서드
// @Transactional
// public AnimalDto.Basic create(AnimalDto.AddReq req) {
// ZooEntity zoo = null;
// if (req.getZooUuid() != null) {
// zoo =
// zooRepository
// .getZooByUuid(req.getZooUuid())
// .orElseThrow(
// () ->
// new EntityNotFoundException("Zoo not found with uuid: " +
// req.getZooUuid()));
// }
// AnimalEntity entity = new AnimalEntity(req.getCategory(), req.getSpecies(), req.getName(),
// zoo);
// AnimalEntity saved = animalRepository.save(entity);
// return saved.toDto();
// }
//
// @Override
// @Transactional
// public void remove(Long id) {
// AnimalEntity getAnimal =
// animalRepository
// .getAnimalByUid(id)
// .orElseThrow(() -> new EntityNotFoundException("getAnimal not found with id: " + id));
// getAnimal.deleted();
// }
//
// @Override
// public AnimalDto.Basic getOneById(Long id) {
// AnimalEntity getAnimal =
// animalRepository
// .getAnimalByUid(id)
// .orElseThrow(() -> new EntityNotFoundException("Zoo not found with id: " + id));
// return getAnimal.toDto();
// }
//
// @Override
// public Page<AnimalDto.Basic> search(AnimalDto.SearchReq searchReq) {
//
// Page<AnimalEntity> animalEntities = animalRepository.listAnimal(searchReq);
// return animalEntities.map(AnimalEntity::toDto);
// }
// }
// package com.kamco.cd.kamcoback.postgres.core;
//
// import com.kamco.cd.kamcoback.common.service.BaseCoreService;
// import com.kamco.cd.kamcoback.postgres.entity.AnimalEntity;
// import com.kamco.cd.kamcoback.postgres.entity.ZooEntity;
// import com.kamco.cd.kamcoback.postgres.repository.AnimalRepository;
// import com.kamco.cd.kamcoback.postgres.repository.ZooRepository;
// import com.kamco.cd.kamcoback.zoo.dto.AnimalDto;
// import jakarta.persistence.EntityNotFoundException;
// import lombok.RequiredArgsConstructor;
// import org.springframework.data.domain.Page;
// import org.springframework.stereotype.Service;
// import org.springframework.transaction.annotation.Transactional;
//
// @Service
// @RequiredArgsConstructor
// @Transactional(readOnly = true)
// public class AnimalCoreService
// implements BaseCoreService<AnimalDto.Basic, Long, AnimalDto.SearchReq> {
//
// private final AnimalRepository animalRepository;
// private final ZooRepository zooRepository;
//
// @Transactional(readOnly = true)
// public AnimalDto.Basic getDataByUuid(String uuid) {
// AnimalEntity getZoo =
// animalRepository
// .getAnimalByUuid(uuid)
// .orElseThrow(() -> new EntityNotFoundException("Zoo not found with uuid: " + uuid));
// return getZoo.toDto();
// }
//
// // AddReq를 받는 추가 메서드
// @Transactional
// public AnimalDto.Basic create(AnimalDto.AddReq req) {
// ZooEntity zoo = null;
// if (req.getZooUuid() != null) {
// zoo =
// zooRepository
// .getZooByUuid(req.getZooUuid())
// .orElseThrow(
// () ->
// new EntityNotFoundException("Zoo not found with uuid: " +
// req.getZooUuid()));
// }
// AnimalEntity entity = new AnimalEntity(req.getCategory(), req.getSpecies(), req.getName(),
// zoo);
// AnimalEntity saved = animalRepository.save(entity);
// return saved.toDto();
// }
//
// @Override
// @Transactional
// public void remove(Long id) {
// AnimalEntity getAnimal =
// animalRepository
// .getAnimalByUid(id)
// .orElseThrow(() -> new EntityNotFoundException("getAnimal not found with id: " + id));
// getAnimal.deleted();
// }
//
// @Override
// public AnimalDto.Basic getOneById(Long id) {
// AnimalEntity getAnimal =
// animalRepository
// .getAnimalByUid(id)
// .orElseThrow(() -> new EntityNotFoundException("Zoo not found with id: " + id));
// return getAnimal.toDto();
// }
//
// @Override
// public Page<AnimalDto.Basic> search(AnimalDto.SearchReq searchReq) {
//
// Page<AnimalEntity> animalEntities = animalRepository.listAnimal(searchReq);
// return animalEntities.map(AnimalEntity::toDto);
// }
// }

View File

@@ -1,62 +1,62 @@
package com.kamco.cd.training.postgres.core;
import com.kamco.cd.training.common.service.BaseCoreService;
import com.kamco.cd.training.log.dto.AuditLogDto;
import com.kamco.cd.training.postgres.repository.log.AuditLogRepository;
import java.time.LocalDate;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class AuditLogCoreService
implements BaseCoreService<AuditLogDto.DailyAuditList, Long, AuditLogDto.searchReq> {
private final AuditLogRepository auditLogRepository;
@Override
public void remove(Long aLong) {}
@Override
public AuditLogDto.DailyAuditList getOneById(Long aLong) {
return null;
}
@Override
public Page<AuditLogDto.DailyAuditList> search(AuditLogDto.searchReq searchReq) {
return null;
}
public Page<AuditLogDto.DailyAuditList> getLogByDaily(
AuditLogDto.searchReq searchRange, LocalDate startDate, LocalDate endDate) {
return auditLogRepository.findLogByDaily(searchRange, startDate, endDate);
}
public Page<AuditLogDto.MenuAuditList> getLogByMenu(
AuditLogDto.searchReq searchRange, String searchValue) {
return auditLogRepository.findLogByMenu(searchRange, searchValue);
}
public Page<AuditLogDto.UserAuditList> getLogByAccount(
AuditLogDto.searchReq searchRange, String searchValue) {
return auditLogRepository.findLogByAccount(searchRange, searchValue);
}
public Page<AuditLogDto.DailyDetail> getLogByDailyResult(
AuditLogDto.searchReq searchRange, LocalDate logDate) {
return auditLogRepository.findLogByDailyResult(searchRange, logDate);
}
public Page<AuditLogDto.MenuDetail> getLogByMenuResult(
AuditLogDto.searchReq searchRange, String menuId) {
return auditLogRepository.findLogByMenuResult(searchRange, menuId);
}
public Page<AuditLogDto.UserDetail> getLogByAccountResult(
AuditLogDto.searchReq searchRange, Long accountId) {
return auditLogRepository.findLogByAccountResult(searchRange, accountId);
}
}
package com.kamco.cd.training.postgres.core;
import com.kamco.cd.training.common.service.BaseCoreService;
import com.kamco.cd.training.log.dto.AuditLogDto;
import com.kamco.cd.training.postgres.repository.log.AuditLogRepository;
import java.time.LocalDate;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class AuditLogCoreService
implements BaseCoreService<AuditLogDto.DailyAuditList, Long, AuditLogDto.searchReq> {
private final AuditLogRepository auditLogRepository;
@Override
public void remove(Long aLong) {}
@Override
public AuditLogDto.DailyAuditList getOneById(Long aLong) {
return null;
}
@Override
public Page<AuditLogDto.DailyAuditList> search(AuditLogDto.searchReq searchReq) {
return null;
}
public Page<AuditLogDto.DailyAuditList> getLogByDaily(
AuditLogDto.searchReq searchRange, LocalDate startDate, LocalDate endDate) {
return auditLogRepository.findLogByDaily(searchRange, startDate, endDate);
}
public Page<AuditLogDto.MenuAuditList> getLogByMenu(
AuditLogDto.searchReq searchRange, String searchValue) {
return auditLogRepository.findLogByMenu(searchRange, searchValue);
}
public Page<AuditLogDto.UserAuditList> getLogByAccount(
AuditLogDto.searchReq searchRange, String searchValue) {
return auditLogRepository.findLogByAccount(searchRange, searchValue);
}
public Page<AuditLogDto.DailyDetail> getLogByDailyResult(
AuditLogDto.searchReq searchRange, LocalDate logDate) {
return auditLogRepository.findLogByDailyResult(searchRange, logDate);
}
public Page<AuditLogDto.MenuDetail> getLogByMenuResult(
AuditLogDto.searchReq searchRange, String menuId) {
return auditLogRepository.findLogByMenuResult(searchRange, menuId);
}
public Page<AuditLogDto.UserDetail> getLogByAccountResult(
AuditLogDto.searchReq searchRange, Long accountId) {
return auditLogRepository.findLogByAccountResult(searchRange, accountId);
}
}

View File

@@ -1,217 +1,217 @@
package com.kamco.cd.training.postgres.core;
import com.kamco.cd.training.code.dto.CommonCodeDto;
import com.kamco.cd.training.code.dto.CommonCodeDto.Basic;
import com.kamco.cd.training.code.dto.CommonCodeDto.SearchReq;
import com.kamco.cd.training.common.service.BaseCoreService;
import com.kamco.cd.training.config.api.ApiResponseDto.ApiResponseCode;
import com.kamco.cd.training.config.api.ApiResponseDto.ResponseObj;
import com.kamco.cd.training.postgres.entity.CommonCodeEntity;
import com.kamco.cd.training.postgres.repository.code.CommonCodeRepository;
import jakarta.persistence.EntityNotFoundException;
import java.util.List;
import java.util.Optional;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
public class CommonCodeCoreService
implements BaseCoreService<CommonCodeDto.Basic, Long, SearchReq> {
private final CommonCodeRepository commonCodeRepository;
/**
* 모두 조회
*
* @return
*/
// @Cacheable(value = "commonCodes")
public List<CommonCodeDto.Basic> findAll() {
return commonCodeRepository.findByAll().stream().map(CommonCodeEntity::toDto).toList();
}
/**
* 등록
*
* @param req
* @return
*/
// @CacheEvict(value = "commonCodes", allEntries = true)
public ResponseObj save(CommonCodeDto.AddReq req) {
String regex = "^[A-Z0-9]+(_[A-Z0-9]+)*$";
boolean isValid = req.getCode().matches(regex);
if (!isValid) {
return new ResponseObj(ApiResponseCode.CONFLICT, "공통코드에 영문 대문자, 숫자, 언더바(_)만 입력 가능합니다.");
}
Long existsCount =
commonCodeRepository.findByParentIdCodeExists(req.getParentId(), req.getCode());
if (existsCount > 0) {
return new ResponseObj(ApiResponseCode.DUPLICATE_DATA, "이미 사용중인 공통코드ID 입니다.");
}
CommonCodeEntity entity =
new CommonCodeEntity(
req.getCode(),
req.getName(),
req.getDescription(),
req.getOrder(),
req.isUsed(),
req.getProps1(),
req.getProps2(),
req.getProps3());
if (req.getParentId() != null) {
CommonCodeEntity parentCommonCodeEntity =
commonCodeRepository
.findById(req.getParentId())
.orElseThrow(
() ->
new EntityNotFoundException(
"parent id 를 찾을 수 없습니다. id : " + req.getParentId()));
entity.addParent(parentCommonCodeEntity);
} else {
entity.addParent(null);
}
commonCodeRepository.save(entity).toDto();
return new ResponseObj(ApiResponseCode.OK, "");
}
/**
* 수정
*
* @param id
* @param req
* @return
*/
// @CacheEvict(value = "commonCodes", allEntries = true)
public ResponseObj update(Long id, CommonCodeDto.ModifyReq req) {
CommonCodeEntity found =
commonCodeRepository
.findByCodeId(id)
.orElseThrow(() -> new EntityNotFoundException("common code 를 찾을 수 없습니다. id : " + id));
found.update(
req.getName(),
req.getDescription(),
req.isUsed(),
req.getProps1(),
req.getProps2(),
req.getProps3());
return new ResponseObj(ApiResponseCode.OK, "");
}
/**
* 순서 변경
*
* @param req
* @return
*/
// @CacheEvict(value = "commonCodes", allEntries = true)
public ResponseObj updateOrder(CommonCodeDto.OrderReq req) {
CommonCodeEntity found =
commonCodeRepository
.findByCodeId(req.getId())
.orElseThrow(
() -> new EntityNotFoundException("common code 를 찾을 수 없습니다. id : " + req.getId()));
found.updateOrder(req.getOrder());
return new ResponseObj(ApiResponseCode.OK, "");
}
public List<CommonCodeDto.Basic> findByCode(String code) {
return commonCodeRepository.findByCode(code).stream().map(CommonCodeEntity::toDto).toList();
}
/**
* 공통코드 이름 조회
*
* @param parentCodeCd
* @param childCodeCd
* @return
*/
public Optional<String> getCode(String parentCodeCd, String childCodeCd) {
return commonCodeRepository.getCode(parentCodeCd, childCodeCd);
}
/**
* 공통코드 삭제
*
* @param id
* @return
*/
// @CacheEvict(value = "commonCodes", allEntries = true)
public ResponseObj removeCode(Long id) {
CommonCodeEntity entity =
commonCodeRepository
.findByCodeId(id)
.orElseThrow(() -> new EntityNotFoundException("code를 찾을 수 없습니다. id " + id));
// 하위코드가 있으면 삭제 불가
if (!entity.getChildren().isEmpty()) {
return new ResponseObj(
ApiResponseCode.UNPROCESSABLE_ENTITY,
"하위에 다른 공통코드를 가지고 있습니다.<br/>하위공통 코드를 이동한 후 삭제할 수 있습니다.");
}
// id 코드 deleted = false 업데이트
entity.deleted();
return new ResponseObj(ApiResponseCode.OK, "");
}
@Override
public void remove(Long aLong) {
// 미사용
}
/**
* id 로 단건 조회
*
* @param id
* @return
*/
@Override
public Basic getOneById(Long id) {
CommonCodeEntity entity =
commonCodeRepository
.findByCodeId(id)
.orElseThrow(() -> new EntityNotFoundException("code를 찾을 수 없습니다. id " + id));
return entity.toDto();
}
@Override
public Page<Basic> search(SearchReq searchReq) {
return null;
}
/**
* 중복 체크
*
* @param parentId
* @param code
* @return
*/
public ResponseObj getCodeCheckDuplicate(Long parentId, String code) {
Long existsCount = commonCodeRepository.findByParentIdCodeExists(parentId, code);
String regex = "^[A-Z0-9]+(_[A-Z0-9]+)*$";
boolean isValid = code.matches(regex);
if (!isValid) {
return new ResponseObj(ApiResponseCode.CONFLICT, "공통코드에 영문 대문자, 숫자, 언더바(_)만 입력 가능합니다.");
}
if (existsCount > 0) {
return new ResponseObj(ApiResponseCode.DUPLICATE_DATA, "이미 사용중인 공통코드ID 입니다.");
}
return new ResponseObj(ApiResponseCode.OK, "");
}
}
package com.kamco.cd.training.postgres.core;
import com.kamco.cd.training.code.dto.CommonCodeDto;
import com.kamco.cd.training.code.dto.CommonCodeDto.Basic;
import com.kamco.cd.training.code.dto.CommonCodeDto.SearchReq;
import com.kamco.cd.training.common.service.BaseCoreService;
import com.kamco.cd.training.config.api.ApiResponseDto.ApiResponseCode;
import com.kamco.cd.training.config.api.ApiResponseDto.ResponseObj;
import com.kamco.cd.training.postgres.entity.CommonCodeEntity;
import com.kamco.cd.training.postgres.repository.code.CommonCodeRepository;
import jakarta.persistence.EntityNotFoundException;
import java.util.List;
import java.util.Optional;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
public class CommonCodeCoreService
implements BaseCoreService<CommonCodeDto.Basic, Long, SearchReq> {
private final CommonCodeRepository commonCodeRepository;
/**
* 모두 조회
*
* @return
*/
// @Cacheable(value = "commonCodes")
public List<CommonCodeDto.Basic> findAll() {
return commonCodeRepository.findByAll().stream().map(CommonCodeEntity::toDto).toList();
}
/**
* 등록
*
* @param req
* @return
*/
// @CacheEvict(value = "commonCodes", allEntries = true)
public ResponseObj save(CommonCodeDto.AddReq req) {
String regex = "^[A-Z0-9]+(_[A-Z0-9]+)*$";
boolean isValid = req.getCode().matches(regex);
if (!isValid) {
return new ResponseObj(ApiResponseCode.CONFLICT, "공통코드에 영문 대문자, 숫자, 언더바(_)만 입력 가능합니다.");
}
Long existsCount =
commonCodeRepository.findByParentIdCodeExists(req.getParentId(), req.getCode());
if (existsCount > 0) {
return new ResponseObj(ApiResponseCode.DUPLICATE_DATA, "이미 사용중인 공통코드ID 입니다.");
}
CommonCodeEntity entity =
new CommonCodeEntity(
req.getCode(),
req.getName(),
req.getDescription(),
req.getOrder(),
req.isUsed(),
req.getProps1(),
req.getProps2(),
req.getProps3());
if (req.getParentId() != null) {
CommonCodeEntity parentCommonCodeEntity =
commonCodeRepository
.findById(req.getParentId())
.orElseThrow(
() ->
new EntityNotFoundException(
"parent id 를 찾을 수 없습니다. id : " + req.getParentId()));
entity.addParent(parentCommonCodeEntity);
} else {
entity.addParent(null);
}
commonCodeRepository.save(entity).toDto();
return new ResponseObj(ApiResponseCode.OK, "");
}
/**
* 수정
*
* @param id
* @param req
* @return
*/
// @CacheEvict(value = "commonCodes", allEntries = true)
public ResponseObj update(Long id, CommonCodeDto.ModifyReq req) {
CommonCodeEntity found =
commonCodeRepository
.findByCodeId(id)
.orElseThrow(() -> new EntityNotFoundException("common code 를 찾을 수 없습니다. id : " + id));
found.update(
req.getName(),
req.getDescription(),
req.isUsed(),
req.getProps1(),
req.getProps2(),
req.getProps3());
return new ResponseObj(ApiResponseCode.OK, "");
}
/**
* 순서 변경
*
* @param req
* @return
*/
// @CacheEvict(value = "commonCodes", allEntries = true)
public ResponseObj updateOrder(CommonCodeDto.OrderReq req) {
CommonCodeEntity found =
commonCodeRepository
.findByCodeId(req.getId())
.orElseThrow(
() -> new EntityNotFoundException("common code 를 찾을 수 없습니다. id : " + req.getId()));
found.updateOrder(req.getOrder());
return new ResponseObj(ApiResponseCode.OK, "");
}
public List<CommonCodeDto.Basic> findByCode(String code) {
return commonCodeRepository.findByCode(code).stream().map(CommonCodeEntity::toDto).toList();
}
/**
* 공통코드 이름 조회
*
* @param parentCodeCd
* @param childCodeCd
* @return
*/
public Optional<String> getCode(String parentCodeCd, String childCodeCd) {
return commonCodeRepository.getCode(parentCodeCd, childCodeCd);
}
/**
* 공통코드 삭제
*
* @param id
* @return
*/
// @CacheEvict(value = "commonCodes", allEntries = true)
public ResponseObj removeCode(Long id) {
CommonCodeEntity entity =
commonCodeRepository
.findByCodeId(id)
.orElseThrow(() -> new EntityNotFoundException("code를 찾을 수 없습니다. id " + id));
// 하위코드가 있으면 삭제 불가
if (!entity.getChildren().isEmpty()) {
return new ResponseObj(
ApiResponseCode.UNPROCESSABLE_ENTITY,
"하위에 다른 공통코드를 가지고 있습니다.<br/>하위공통 코드를 이동한 후 삭제할 수 있습니다.");
}
// id 코드 deleted = false 업데이트
entity.deleted();
return new ResponseObj(ApiResponseCode.OK, "");
}
@Override
public void remove(Long aLong) {
// 미사용
}
/**
* id 로 단건 조회
*
* @param id
* @return
*/
@Override
public Basic getOneById(Long id) {
CommonCodeEntity entity =
commonCodeRepository
.findByCodeId(id)
.orElseThrow(() -> new EntityNotFoundException("code를 찾을 수 없습니다. id " + id));
return entity.toDto();
}
@Override
public Page<Basic> search(SearchReq searchReq) {
return null;
}
/**
* 중복 체크
*
* @param parentId
* @param code
* @return
*/
public ResponseObj getCodeCheckDuplicate(Long parentId, String code) {
Long existsCount = commonCodeRepository.findByParentIdCodeExists(parentId, code);
String regex = "^[A-Z0-9]+(_[A-Z0-9]+)*$";
boolean isValid = code.matches(regex);
if (!isValid) {
return new ResponseObj(ApiResponseCode.CONFLICT, "공통코드에 영문 대문자, 숫자, 언더바(_)만 입력 가능합니다.");
}
if (existsCount > 0) {
return new ResponseObj(ApiResponseCode.DUPLICATE_DATA, "이미 사용중인 공통코드ID 입니다.");
}
return new ResponseObj(ApiResponseCode.OK, "");
}
}

View File

@@ -1,276 +1,276 @@
package com.kamco.cd.training.postgres.core;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.kamco.cd.training.common.exception.NotFoundException;
import com.kamco.cd.training.common.service.BaseCoreService;
import com.kamco.cd.training.dataset.dto.DatasetDto;
import com.kamco.cd.training.model.dto.ModelMngDto;
import com.kamco.cd.training.postgres.entity.DatasetEntity;
import com.kamco.cd.training.postgres.repository.dataset.DatasetRepository;
import java.time.ZonedDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
@Slf4j
public class DatasetCoreService
implements BaseCoreService<DatasetDto.Basic, Long, DatasetDto.SearchReq> {
private final DatasetRepository datasetRepository;
private final ObjectMapper objectMapper;
/**
* 학습 데이터 삭제
*
* @param id 데이터셋 ID
*/
@Override
public void remove(Long id) {
DatasetEntity entity =
datasetRepository
.findById(id)
.orElseThrow(() -> new NotFoundException("데이터셋을 찾을 수 없습니다. ID: " + id));
entity.setDeleted(true);
datasetRepository.save(entity);
}
public void remove(UUID id) {
DatasetEntity entity =
datasetRepository
.findByUuid(id)
.orElseThrow(() -> new NotFoundException("데이터셋을 찾을 수 없습니다. ID: " + id));
entity.setDeleted(true);
datasetRepository.save(entity);
}
@Override
public DatasetDto.Basic getOneById(Long id) {
DatasetEntity entity =
datasetRepository
.findById(id)
.orElseThrow(() -> new NotFoundException("데이터셋을 찾을 수 없습니다. ID: " + id));
if (entity.getDeleted()) {
throw new NotFoundException("삭제된 데이터셋입니다. ID: " + id);
}
return entity.toDto();
}
public DatasetDto.Basic getOneByUuid(UUID id) {
DatasetEntity entity =
datasetRepository
.findByUuid(id)
.orElseThrow(() -> new NotFoundException("데이터셋을 찾을 수 없습니다. uuid: " + id));
return entity.toDto();
}
@Override
public Page<DatasetDto.Basic> search(DatasetDto.SearchReq searchReq) {
Page<DatasetEntity> entityPage = datasetRepository.findDatasetList(searchReq);
return entityPage.map(DatasetEntity::toDto);
}
/**
* 학습데이터 조회
*
* @param searchReq 검색 조건
* @return 페이징 처리된 데이터셋 목록
*/
public Page<DatasetDto.Basic> findDatasetList(DatasetDto.SearchReq searchReq) {
return search(searchReq);
}
/**
* 학습데이터 등록
*
* @param registerReq 등록 요청 데이터
* @return 등록된 데이터셋 정보
*/
public DatasetDto.Basic save(DatasetDto.RegisterReq registerReq) {
// 먼저 id1 필드를 임시값(0)으로 설정하여 저장
DatasetEntity entity = new DatasetEntity();
entity.setTitle(registerReq.getTitle());
entity.setYear(registerReq.getYear());
entity.setGroupTitle("PRODUCTION");
entity.setDataYear(registerReq.getYear());
entity.setRoundNo(registerReq.getRoundNo() != null ? registerReq.getRoundNo() : 1L);
entity.setMemo(registerReq.getMemo());
entity.setStatus("READY");
entity.setDataType("CREATE");
entity.setTotalItems(0L);
entity.setTotalSize(0L);
entity.setItemCount(0L);
entity.setDeleted(false);
entity.setCreatedDttm(ZonedDateTime.now());
entity.setId1(0L); // 임시값
DatasetEntity savedEntity = datasetRepository.save(entity);
// 저장 후 id1을 dataset_uid와 동일하게 업데이트
savedEntity.setId1(savedEntity.getId());
savedEntity = datasetRepository.save(savedEntity);
return savedEntity.toDto();
}
/**
* 학습 데이터 수정
*
* @param updateReq 수정 요청 데이터
* @return 수정된 데이터셋 정보
*/
public void update(UUID uuid, DatasetDto.UpdateReq updateReq) {
DatasetEntity entity =
datasetRepository
.findByUuid(uuid)
.orElseThrow(() -> new NotFoundException("데이터셋을 찾을 수 없습니다. uuid: " + uuid));
if (StringUtils.isNotBlank(updateReq.getTitle())) {
entity.setTitle(updateReq.getTitle());
}
if (StringUtils.isNotBlank(updateReq.getMemo())) {
entity.setMemo(updateReq.getMemo());
}
datasetRepository.save(entity);
}
/**
* 학습데이터 삭제
*
* @param uuid 삭제 요청 (데이터셋 ID 목록)
*/
public void deleteDatasets(UUID uuid) {
remove(uuid);
}
public DatasetDto.Summary getDatasetSummary(DatasetDto.SummaryReq summaryReq) {
long totalMapSheets = 0;
long totalFileSize = 0;
for (Long datasetId : summaryReq.getDatasetIds()) {
DatasetEntity entity =
datasetRepository
.findById(datasetId)
.orElseThrow(() -> new NotFoundException("데이터셋을 찾을 수 없습니다. ID: " + datasetId));
if (!entity.getDeleted()) {
totalMapSheets += entity.getTotalItems() != null ? entity.getTotalItems() : 0;
totalFileSize += entity.getTotalSize() != null ? entity.getTotalSize() : 0;
}
}
double averageMapSheets =
!summaryReq.getDatasetIds().isEmpty()
? (double) totalMapSheets / summaryReq.getDatasetIds().size()
: 0;
return new DatasetDto.Summary(
summaryReq.getDatasetIds().size(), totalMapSheets, totalFileSize, averageMapSheets);
}
/**
* 활성 데이터셋 전체 조회 (학습 관리용)
*
* @return 데이터셋 정보 목록
*/
public List<ModelMngDto.DatasetInfo> findAllActiveDatasetsForTraining() {
List<DatasetEntity> entities = datasetRepository.findByDeletedOrderByCreatedDttmDesc(false);
return entities.stream()
.map(
entity -> {
// totalSize를 읽기 쉬운 형식으로 변환
String totalSizeStr = formatFileSize(entity.getTotalSize());
// classCounts JSON 파싱
Map<String, Integer> classCounts = entity.getClassCounts();
return ModelMngDto.DatasetInfo.builder()
.id(entity.getId())
.title(entity.getTitle())
.groupTitle(entity.getGroupTitle())
.totalItems(entity.getTotalItems())
.totalSize(totalSizeStr)
.classCounts(classCounts)
.memo(entity.getMemo())
.createdDttm(entity.getCreatedDttm())
.build();
})
.toList();
}
/**
* JSON 문자열을 Map으로 파싱
*
* @param jsonStr JSON 문자열
* @return 클래스별 카운트 맵
*/
private Map<String, Integer> parseClassCounts(String jsonStr) {
if (jsonStr == null || jsonStr.trim().isEmpty()) {
return new HashMap<>();
}
try {
return objectMapper.readValue(jsonStr, new TypeReference<Map<String, Integer>>() {});
} catch (Exception e) {
log.warn("클래스 통계 JSON 파싱 실패: {}", jsonStr, e);
return new HashMap<>();
}
}
/**
* 데이터셋의 클래스 통계 계산 및 저장
*
* @param datasetId 데이터셋 ID
* @param classCounts 클래스별 카운트
*/
public void updateClassCounts(Long datasetId, Map<String, Integer> classCounts) {
DatasetEntity entity =
datasetRepository
.findById(datasetId)
.orElseThrow(() -> new NotFoundException("데이터셋을 찾을 수 없습니다. ID: " + datasetId));
try {
entity.setClassCounts(classCounts);
datasetRepository.save(entity);
log.info("데이터셋 클래스 통계 업데이트 완료: datasetId={}, classes={}", datasetId, classCounts.keySet());
} catch (Exception e) {
log.error("클래스 통계 JSON 변환 실패: datasetId={}", datasetId, e);
}
}
/**
* 파일 크기를 읽기 쉬운 형식으로 변환
*
* @param size 바이트 단위 크기
* @return 형식화된 문자열 (예: "1.5GB")
*/
private String formatFileSize(Long size) {
if (size == null || size == 0) {
return "0 GB";
}
double gb = size / (1024.0 * 1024.0 * 1024.0);
if (gb >= 1.0) {
return String.format("%.2f GB", gb);
}
double mb = size / (1024.0 * 1024.0);
if (mb >= 1.0) {
return String.format("%.2f MB", mb);
}
double kb = size / 1024.0;
return String.format("%.2f KB", kb);
}
}
package com.kamco.cd.training.postgres.core;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.kamco.cd.training.common.exception.NotFoundException;
import com.kamco.cd.training.common.service.BaseCoreService;
import com.kamco.cd.training.dataset.dto.DatasetDto;
import com.kamco.cd.training.model.dto.ModelMngDto;
import com.kamco.cd.training.postgres.entity.DatasetEntity;
import com.kamco.cd.training.postgres.repository.dataset.DatasetRepository;
import java.time.ZonedDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
@Slf4j
public class DatasetCoreService
implements BaseCoreService<DatasetDto.Basic, Long, DatasetDto.SearchReq> {
private final DatasetRepository datasetRepository;
private final ObjectMapper objectMapper;
/**
* 학습 데이터 삭제
*
* @param id 데이터셋 ID
*/
@Override
public void remove(Long id) {
DatasetEntity entity =
datasetRepository
.findById(id)
.orElseThrow(() -> new NotFoundException("데이터셋을 찾을 수 없습니다. ID: " + id));
entity.setDeleted(true);
datasetRepository.save(entity);
}
public void remove(UUID id) {
DatasetEntity entity =
datasetRepository
.findByUuid(id)
.orElseThrow(() -> new NotFoundException("데이터셋을 찾을 수 없습니다. ID: " + id));
entity.setDeleted(true);
datasetRepository.save(entity);
}
@Override
public DatasetDto.Basic getOneById(Long id) {
DatasetEntity entity =
datasetRepository
.findById(id)
.orElseThrow(() -> new NotFoundException("데이터셋을 찾을 수 없습니다. ID: " + id));
if (entity.getDeleted()) {
throw new NotFoundException("삭제된 데이터셋입니다. ID: " + id);
}
return entity.toDto();
}
public DatasetDto.Basic getOneByUuid(UUID id) {
DatasetEntity entity =
datasetRepository
.findByUuid(id)
.orElseThrow(() -> new NotFoundException("데이터셋을 찾을 수 없습니다. uuid: " + id));
return entity.toDto();
}
@Override
public Page<DatasetDto.Basic> search(DatasetDto.SearchReq searchReq) {
Page<DatasetEntity> entityPage = datasetRepository.findDatasetList(searchReq);
return entityPage.map(DatasetEntity::toDto);
}
/**
* 학습데이터 조회
*
* @param searchReq 검색 조건
* @return 페이징 처리된 데이터셋 목록
*/
public Page<DatasetDto.Basic> findDatasetList(DatasetDto.SearchReq searchReq) {
return search(searchReq);
}
/**
* 학습데이터 등록
*
* @param registerReq 등록 요청 데이터
* @return 등록된 데이터셋 정보
*/
public DatasetDto.Basic save(DatasetDto.RegisterReq registerReq) {
// 먼저 id1 필드를 임시값(0)으로 설정하여 저장
DatasetEntity entity = new DatasetEntity();
entity.setTitle(registerReq.getTitle());
entity.setYear(registerReq.getYear());
entity.setGroupTitle("PRODUCTION");
entity.setDataYear(registerReq.getYear());
entity.setRoundNo(registerReq.getRoundNo() != null ? registerReq.getRoundNo() : 1L);
entity.setMemo(registerReq.getMemo());
entity.setStatus("READY");
entity.setDataType("CREATE");
entity.setTotalItems(0L);
entity.setTotalSize(0L);
entity.setItemCount(0L);
entity.setDeleted(false);
entity.setCreatedDttm(ZonedDateTime.now());
entity.setId1(0L); // 임시값
DatasetEntity savedEntity = datasetRepository.save(entity);
// 저장 후 id1을 dataset_uid와 동일하게 업데이트
savedEntity.setId1(savedEntity.getId());
savedEntity = datasetRepository.save(savedEntity);
return savedEntity.toDto();
}
/**
* 학습 데이터 수정
*
* @param updateReq 수정 요청 데이터
* @return 수정된 데이터셋 정보
*/
public void update(UUID uuid, DatasetDto.UpdateReq updateReq) {
DatasetEntity entity =
datasetRepository
.findByUuid(uuid)
.orElseThrow(() -> new NotFoundException("데이터셋을 찾을 수 없습니다. uuid: " + uuid));
if (StringUtils.isNotBlank(updateReq.getTitle())) {
entity.setTitle(updateReq.getTitle());
}
if (StringUtils.isNotBlank(updateReq.getMemo())) {
entity.setMemo(updateReq.getMemo());
}
datasetRepository.save(entity);
}
/**
* 학습데이터 삭제
*
* @param uuid 삭제 요청 (데이터셋 ID 목록)
*/
public void deleteDatasets(UUID uuid) {
remove(uuid);
}
public DatasetDto.Summary getDatasetSummary(DatasetDto.SummaryReq summaryReq) {
long totalMapSheets = 0;
long totalFileSize = 0;
for (Long datasetId : summaryReq.getDatasetIds()) {
DatasetEntity entity =
datasetRepository
.findById(datasetId)
.orElseThrow(() -> new NotFoundException("데이터셋을 찾을 수 없습니다. ID: " + datasetId));
if (!entity.getDeleted()) {
totalMapSheets += entity.getTotalItems() != null ? entity.getTotalItems() : 0;
totalFileSize += entity.getTotalSize() != null ? entity.getTotalSize() : 0;
}
}
double averageMapSheets =
!summaryReq.getDatasetIds().isEmpty()
? (double) totalMapSheets / summaryReq.getDatasetIds().size()
: 0;
return new DatasetDto.Summary(
summaryReq.getDatasetIds().size(), totalMapSheets, totalFileSize, averageMapSheets);
}
/**
* 활성 데이터셋 전체 조회 (학습 관리용)
*
* @return 데이터셋 정보 목록
*/
public List<ModelMngDto.DatasetInfo> findAllActiveDatasetsForTraining() {
List<DatasetEntity> entities = datasetRepository.findByDeletedOrderByCreatedDttmDesc(false);
return entities.stream()
.map(
entity -> {
// totalSize를 읽기 쉬운 형식으로 변환
String totalSizeStr = formatFileSize(entity.getTotalSize());
// classCounts JSON 파싱
Map<String, Integer> classCounts = entity.getClassCounts();
return ModelMngDto.DatasetInfo.builder()
.id(entity.getId())
.title(entity.getTitle())
.groupTitle(entity.getGroupTitle())
.totalItems(entity.getTotalItems())
.totalSize(totalSizeStr)
.classCounts(classCounts)
.memo(entity.getMemo())
.createdDttm(entity.getCreatedDttm())
.build();
})
.toList();
}
/**
* JSON 문자열을 Map으로 파싱
*
* @param jsonStr JSON 문자열
* @return 클래스별 카운트 맵
*/
private Map<String, Integer> parseClassCounts(String jsonStr) {
if (jsonStr == null || jsonStr.trim().isEmpty()) {
return new HashMap<>();
}
try {
return objectMapper.readValue(jsonStr, new TypeReference<Map<String, Integer>>() {});
} catch (Exception e) {
log.warn("클래스 통계 JSON 파싱 실패: {}", jsonStr, e);
return new HashMap<>();
}
}
/**
* 데이터셋의 클래스 통계 계산 및 저장
*
* @param datasetId 데이터셋 ID
* @param classCounts 클래스별 카운트
*/
public void updateClassCounts(Long datasetId, Map<String, Integer> classCounts) {
DatasetEntity entity =
datasetRepository
.findById(datasetId)
.orElseThrow(() -> new NotFoundException("데이터셋을 찾을 수 없습니다. ID: " + datasetId));
try {
entity.setClassCounts(classCounts);
datasetRepository.save(entity);
log.info("데이터셋 클래스 통계 업데이트 완료: datasetId={}, classes={}", datasetId, classCounts.keySet());
} catch (Exception e) {
log.error("클래스 통계 JSON 변환 실패: datasetId={}", datasetId, e);
}
}
/**
* 파일 크기를 읽기 쉬운 형식으로 변환
*
* @param size 바이트 단위 크기
* @return 형식화된 문자열 (예: "1.5GB")
*/
private String formatFileSize(Long size) {
if (size == null || size == 0) {
return "0 GB";
}
double gb = size / (1024.0 * 1024.0 * 1024.0);
if (gb >= 1.0) {
return String.format("%.2f GB", gb);
}
double mb = size / (1024.0 * 1024.0);
if (mb >= 1.0) {
return String.format("%.2f MB", mb);
}
double kb = size / 1024.0;
return String.format("%.2f KB", kb);
}
}

View File

@@ -1,35 +1,35 @@
package com.kamco.cd.training.postgres.core;
import com.kamco.cd.training.common.service.BaseCoreService;
import com.kamco.cd.training.log.dto.ErrorLogDto;
import com.kamco.cd.training.postgres.repository.log.ErrorLogRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class ErrorLogCoreService
implements BaseCoreService<ErrorLogDto.Basic, Long, ErrorLogDto.ErrorSearchReq> {
private final ErrorLogRepository errorLogRepository;
public Page<ErrorLogDto.Basic> findLogByError(ErrorLogDto.ErrorSearchReq searchReq) {
return errorLogRepository.findLogByError(searchReq);
}
@Override
public void remove(Long aLong) {}
@Override
public ErrorLogDto.Basic getOneById(Long aLong) {
return null;
}
@Override
public Page<ErrorLogDto.Basic> search(ErrorLogDto.ErrorSearchReq searchReq) {
return null;
}
}
package com.kamco.cd.training.postgres.core;
import com.kamco.cd.training.common.service.BaseCoreService;
import com.kamco.cd.training.log.dto.ErrorLogDto;
import com.kamco.cd.training.postgres.repository.log.ErrorLogRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class ErrorLogCoreService
implements BaseCoreService<ErrorLogDto.Basic, Long, ErrorLogDto.ErrorSearchReq> {
private final ErrorLogRepository errorLogRepository;
public Page<ErrorLogDto.Basic> findLogByError(ErrorLogDto.ErrorSearchReq searchReq) {
return errorLogRepository.findLogByError(searchReq);
}
@Override
public void remove(Long aLong) {}
@Override
public ErrorLogDto.Basic getOneById(Long aLong) {
return null;
}
@Override
public Page<ErrorLogDto.Basic> search(ErrorLogDto.ErrorSearchReq searchReq) {
return null;
}
}

View File

@@ -1,337 +1,337 @@
package com.kamco.cd.training.postgres.core;
import com.kamco.cd.training.common.exception.BadRequestException;
import com.kamco.cd.training.common.exception.NotFoundException;
import com.kamco.cd.training.model.dto.ModelMngDto;
import com.kamco.cd.training.postgres.entity.ModelHyperParamEntity;
import com.kamco.cd.training.postgres.repository.model.ModelHyperParamRepository;
import java.time.ZonedDateTime;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
public class HyperParamCoreService {
private final ModelHyperParamRepository hyperParamRepository;
/**
* 하이퍼파라미터 전체 조회 (삭제되지 않은 것만)
*
* @return 하이퍼파라미터 목록
*/
public List<ModelMngDto.HyperParamInfo> findAllActiveHyperParams() {
List<ModelHyperParamEntity> entities =
hyperParamRepository.findByDelYnOrderByCreatedDttmDesc("N");
return entities.stream().map(this::mapToHyperParamInfo).toList();
}
private ModelMngDto.HyperParamInfo mapToHyperParamInfo(ModelHyperParamEntity entity) {
return ModelMngDto.HyperParamInfo.builder()
.hyperVer(entity.getHyperVer())
// Important
.backbone(entity.getBackbone())
.inputSize(entity.getInputSize())
.cropSize(entity.getCropSize())
.epochCnt(entity.getEpochCnt())
.batchSize(entity.getBatchSize())
// Architecture
.dropPathRate(entity.getDropPathRate())
.frozenStages(entity.getFrozenStages())
.neckPolicy(entity.getNeckPolicy())
.decoderChannels(entity.getDecoderChannels())
.classWeight(entity.getClassWeight())
.numLayers(entity.getNumLayers())
// Optimization
.learningRate(entity.getLearningRate())
.weightDecay(entity.getWeightDecay())
.layerDecayRate(entity.getLayerDecayRate())
.ddpFindUnusedParams(entity.getDdpFindUnusedParams())
.ignoreIndex(entity.getIgnoreIndex())
// Data
.trainNumWorkers(entity.getTrainNumWorkers())
.valNumWorkers(entity.getValNumWorkers())
.testNumWorkers(entity.getTestNumWorkers())
.trainShuffle(entity.getTrainShuffle())
.trainPersistent(entity.getTrainPersistent())
.valPersistent(entity.getValPersistent())
// Evaluation
.metrics(entity.getMetrics())
.saveBest(entity.getSaveBest())
.saveBestRule(entity.getSaveBestRule())
.valInterval(entity.getValInterval())
.logInterval(entity.getLogInterval())
.visInterval(entity.getVisInterval())
// Hardware
.gpuCnt(entity.getGpuCnt())
.gpuIds(entity.getGpuIds())
.masterPort(entity.getMasterPort())
// Augmentation
.rotProb(entity.getRotProb())
.flipProb(entity.getFlipProb())
.rotDegree(entity.getRotDegree())
.exchangeProb(entity.getExchangeProb())
.brightnessDelta(entity.getBrightnessDelta())
.contrastRange(entity.getContrastRange())
.saturationRange(entity.getSaturationRange())
.hueDelta(entity.getHueDelta())
// Legacy
.dropoutRatio(entity.getDropoutRatio())
.cnnFilterCnt(entity.getCnnFilterCnt())
// Common
.memo(entity.getMemo())
.createdDttm(entity.getCreatedDttm())
.build();
}
/**
* 하이퍼파라미터 등록
*
* @param createReq 등록 요청
* @return 등록된 버전명
*/
public String createHyperParam(ModelMngDto.HyperParamCreateReq createReq) {
// 중복 체크
if (hyperParamRepository.existsById(createReq.getNewHyperVer())) {
throw new BadRequestException("이미 존재하는 버전입니다: " + createReq.getNewHyperVer());
}
// 기준 버전 조회
ModelHyperParamEntity baseEntity =
hyperParamRepository
.findById(createReq.getBaseHyperVer())
.orElseThrow(
() -> new NotFoundException("기준 버전을 찾을 수 없습니다: " + createReq.getBaseHyperVer()));
// 신규 엔티티 생성 (기준 값 복사 후 변경된 값만 적용)
ModelHyperParamEntity entity = new ModelHyperParamEntity();
entity.setHyperVer(createReq.getNewHyperVer());
// Important
entity.setBackbone(
createReq.getBackbone() != null ? createReq.getBackbone() : baseEntity.getBackbone());
entity.setInputSize(
createReq.getInputSize() != null ? createReq.getInputSize() : baseEntity.getInputSize());
entity.setCropSize(
createReq.getCropSize() != null ? createReq.getCropSize() : baseEntity.getCropSize());
entity.setEpochCnt(
createReq.getEpochCnt() != null ? createReq.getEpochCnt() : baseEntity.getEpochCnt());
entity.setBatchSize(
createReq.getBatchSize() != null ? createReq.getBatchSize() : baseEntity.getBatchSize());
// Architecture
entity.setDropPathRate(
createReq.getDropPathRate() != null
? createReq.getDropPathRate()
: baseEntity.getDropPathRate());
entity.setFrozenStages(
createReq.getFrozenStages() != null
? createReq.getFrozenStages()
: baseEntity.getFrozenStages());
entity.setNeckPolicy(
createReq.getNeckPolicy() != null ? createReq.getNeckPolicy() : baseEntity.getNeckPolicy());
entity.setDecoderChannels(
createReq.getDecoderChannels() != null
? createReq.getDecoderChannels()
: baseEntity.getDecoderChannels());
entity.setClassWeight(
createReq.getClassWeight() != null
? createReq.getClassWeight()
: baseEntity.getClassWeight());
entity.setNumLayers(
createReq.getNumLayers() != null ? createReq.getNumLayers() : baseEntity.getNumLayers());
// Optimization
entity.setLearningRate(
createReq.getLearningRate() != null
? createReq.getLearningRate()
: baseEntity.getLearningRate());
entity.setWeightDecay(
createReq.getWeightDecay() != null
? createReq.getWeightDecay()
: baseEntity.getWeightDecay());
entity.setLayerDecayRate(
createReq.getLayerDecayRate() != null
? createReq.getLayerDecayRate()
: baseEntity.getLayerDecayRate());
entity.setDdpFindUnusedParams(
createReq.getDdpFindUnusedParams() != null
? createReq.getDdpFindUnusedParams()
: baseEntity.getDdpFindUnusedParams());
entity.setIgnoreIndex(
createReq.getIgnoreIndex() != null
? createReq.getIgnoreIndex()
: baseEntity.getIgnoreIndex());
// Data
entity.setTrainNumWorkers(
createReq.getTrainNumWorkers() != null
? createReq.getTrainNumWorkers()
: baseEntity.getTrainNumWorkers());
entity.setValNumWorkers(
createReq.getValNumWorkers() != null
? createReq.getValNumWorkers()
: baseEntity.getValNumWorkers());
entity.setTestNumWorkers(
createReq.getTestNumWorkers() != null
? createReq.getTestNumWorkers()
: baseEntity.getTestNumWorkers());
entity.setTrainShuffle(
createReq.getTrainShuffle() != null
? createReq.getTrainShuffle()
: baseEntity.getTrainShuffle());
entity.setTrainPersistent(
createReq.getTrainPersistent() != null
? createReq.getTrainPersistent()
: baseEntity.getTrainPersistent());
entity.setValPersistent(
createReq.getValPersistent() != null
? createReq.getValPersistent()
: baseEntity.getValPersistent());
// Evaluation
entity.setMetrics(
createReq.getMetrics() != null ? createReq.getMetrics() : baseEntity.getMetrics());
entity.setSaveBest(
createReq.getSaveBest() != null ? createReq.getSaveBest() : baseEntity.getSaveBest());
entity.setSaveBestRule(
createReq.getSaveBestRule() != null
? createReq.getSaveBestRule()
: baseEntity.getSaveBestRule());
entity.setValInterval(
createReq.getValInterval() != null
? createReq.getValInterval()
: baseEntity.getValInterval());
entity.setLogInterval(
createReq.getLogInterval() != null
? createReq.getLogInterval()
: baseEntity.getLogInterval());
entity.setVisInterval(
createReq.getVisInterval() != null
? createReq.getVisInterval()
: baseEntity.getVisInterval());
// Hardware
entity.setGpuCnt(
createReq.getGpuCnt() != null ? createReq.getGpuCnt() : baseEntity.getGpuCnt());
entity.setGpuIds(
createReq.getGpuIds() != null ? createReq.getGpuIds() : baseEntity.getGpuIds());
entity.setMasterPort(
createReq.getMasterPort() != null ? createReq.getMasterPort() : baseEntity.getMasterPort());
// Augmentation
entity.setRotProb(
createReq.getRotProb() != null ? createReq.getRotProb() : baseEntity.getRotProb());
entity.setFlipProb(
createReq.getFlipProb() != null ? createReq.getFlipProb() : baseEntity.getFlipProb());
entity.setRotDegree(
createReq.getRotDegree() != null ? createReq.getRotDegree() : baseEntity.getRotDegree());
entity.setExchangeProb(
createReq.getExchangeProb() != null
? createReq.getExchangeProb()
: baseEntity.getExchangeProb());
entity.setBrightnessDelta(
createReq.getBrightnessDelta() != null
? createReq.getBrightnessDelta()
: baseEntity.getBrightnessDelta());
entity.setContrastRange(
createReq.getContrastRange() != null
? createReq.getContrastRange()
: baseEntity.getContrastRange());
entity.setSaturationRange(
createReq.getSaturationRange() != null
? createReq.getSaturationRange()
: baseEntity.getSaturationRange());
entity.setHueDelta(
createReq.getHueDelta() != null ? createReq.getHueDelta() : baseEntity.getHueDelta());
// Legacy
entity.setDropoutRatio(
createReq.getDropoutRatio() != null
? createReq.getDropoutRatio()
: baseEntity.getDropoutRatio());
entity.setCnnFilterCnt(
createReq.getCnnFilterCnt() != null
? createReq.getCnnFilterCnt()
: baseEntity.getCnnFilterCnt());
// Common
entity.setMemo(createReq.getMemo());
entity.setDelYn("N");
entity.setCreatedDttm(ZonedDateTime.now());
ModelHyperParamEntity saved = hyperParamRepository.save(entity);
return saved.getHyperVer();
}
/**
* 하이퍼파라미터 단건 조회
*
* @param hyperVer 하이퍼파라미터 버전
* @return 하이퍼파라미터 정보
*/
public ModelMngDto.HyperParamInfo findByHyperVer(String hyperVer) {
ModelHyperParamEntity entity =
hyperParamRepository
.findById(hyperVer)
.orElseThrow(() -> new NotFoundException("하이퍼파라미터를 찾을 수 없습니다: " + hyperVer));
if ("Y".equals(entity.getDelYn())) {
throw new NotFoundException("삭제된 하이퍼파라미터입니다: " + hyperVer);
}
return mapToHyperParamInfo(entity);
}
/**
* 하이퍼파라미터 수정 (기존 버전은 수정 불가)
*
* @param hyperVer 하이퍼파라미터 버전
* @param updateReq 수정 요청
*/
public void updateHyperParam(String hyperVer, ModelMngDto.HyperParamCreateReq updateReq) {
// 기존 버전은 수정 불가
throw new BadRequestException("기존 버전은 수정할 수 없습니다. 신규 버전을 생성해주세요.");
}
/**
* 하이퍼파라미터 삭제 (논리 삭제)
*
* @param hyperVer 하이퍼파라미터 버전
*/
public void deleteHyperParam(String hyperVer) {
// H1은 디폴트 버전이므로 삭제 불가
if ("H1".equals(hyperVer)) {
throw new BadRequestException("H1은 디폴트 하이퍼파라미터 버전이므로 삭제할 수 없습니다.");
}
ModelHyperParamEntity entity =
hyperParamRepository
.findById(hyperVer)
.orElseThrow(() -> new NotFoundException("하이퍼파라미터를 찾을 수 없습니다: " + hyperVer));
if ("Y".equals(entity.getDelYn())) {
throw new BadRequestException("이미 삭제된 하이퍼파라미터입니다: " + hyperVer);
}
// 논리 삭제 처리
entity.setDelYn("Y");
hyperParamRepository.save(entity);
}
/**
* 첫 번째 하이퍼파라미터 버전 조회 (H1 확인용)
*
* @return 첫 번째 하이퍼파라미터 버전
*/
public String getFirstHyperParamVersion() {
List<ModelHyperParamEntity> entities =
hyperParamRepository.findByDelYnOrderByCreatedDttmDesc("N");
if (entities.isEmpty()) {
throw new NotFoundException("하이퍼파라미터가 존재하지 않습니다.");
}
// 가장 오래된 것이 H1이므로 리스트의 마지막 요소 반환
return entities.get(entities.size() - 1).getHyperVer();
}
}
package com.kamco.cd.training.postgres.core;
import com.kamco.cd.training.common.exception.BadRequestException;
import com.kamco.cd.training.common.exception.NotFoundException;
import com.kamco.cd.training.model.dto.ModelMngDto;
import com.kamco.cd.training.postgres.entity.ModelHyperParamEntity;
import com.kamco.cd.training.postgres.repository.model.ModelHyperParamRepository;
import java.time.ZonedDateTime;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
public class HyperParamCoreService {
private final ModelHyperParamRepository hyperParamRepository;
/**
* 하이퍼파라미터 전체 조회 (삭제되지 않은 것만)
*
* @return 하이퍼파라미터 목록
*/
public List<ModelMngDto.HyperParamInfo> findAllActiveHyperParams() {
List<ModelHyperParamEntity> entities =
hyperParamRepository.findByDelYnOrderByCreatedDttmDesc("N");
return entities.stream().map(this::mapToHyperParamInfo).toList();
}
private ModelMngDto.HyperParamInfo mapToHyperParamInfo(ModelHyperParamEntity entity) {
return ModelMngDto.HyperParamInfo.builder()
.hyperVer(entity.getHyperVer())
// Important
.backbone(entity.getBackbone())
.inputSize(entity.getInputSize())
.cropSize(entity.getCropSize())
.epochCnt(entity.getEpochCnt())
.batchSize(entity.getBatchSize())
// Architecture
.dropPathRate(entity.getDropPathRate())
.frozenStages(entity.getFrozenStages())
.neckPolicy(entity.getNeckPolicy())
.decoderChannels(entity.getDecoderChannels())
.classWeight(entity.getClassWeight())
.numLayers(entity.getNumLayers())
// Optimization
.learningRate(entity.getLearningRate())
.weightDecay(entity.getWeightDecay())
.layerDecayRate(entity.getLayerDecayRate())
.ddpFindUnusedParams(entity.getDdpFindUnusedParams())
.ignoreIndex(entity.getIgnoreIndex())
// Data
.trainNumWorkers(entity.getTrainNumWorkers())
.valNumWorkers(entity.getValNumWorkers())
.testNumWorkers(entity.getTestNumWorkers())
.trainShuffle(entity.getTrainShuffle())
.trainPersistent(entity.getTrainPersistent())
.valPersistent(entity.getValPersistent())
// Evaluation
.metrics(entity.getMetrics())
.saveBest(entity.getSaveBest())
.saveBestRule(entity.getSaveBestRule())
.valInterval(entity.getValInterval())
.logInterval(entity.getLogInterval())
.visInterval(entity.getVisInterval())
// Hardware
.gpuCnt(entity.getGpuCnt())
.gpuIds(entity.getGpuIds())
.masterPort(entity.getMasterPort())
// Augmentation
.rotProb(entity.getRotProb())
.flipProb(entity.getFlipProb())
.rotDegree(entity.getRotDegree())
.exchangeProb(entity.getExchangeProb())
.brightnessDelta(entity.getBrightnessDelta())
.contrastRange(entity.getContrastRange())
.saturationRange(entity.getSaturationRange())
.hueDelta(entity.getHueDelta())
// Legacy
.dropoutRatio(entity.getDropoutRatio())
.cnnFilterCnt(entity.getCnnFilterCnt())
// Common
.memo(entity.getMemo())
.createdDttm(entity.getCreatedDttm())
.build();
}
/**
* 하이퍼파라미터 등록
*
* @param createReq 등록 요청
* @return 등록된 버전명
*/
public String createHyperParam(ModelMngDto.HyperParamCreateReq createReq) {
// 중복 체크
if (hyperParamRepository.existsById(createReq.getNewHyperVer())) {
throw new BadRequestException("이미 존재하는 버전입니다: " + createReq.getNewHyperVer());
}
// 기준 버전 조회
ModelHyperParamEntity baseEntity =
hyperParamRepository
.findById(createReq.getBaseHyperVer())
.orElseThrow(
() -> new NotFoundException("기준 버전을 찾을 수 없습니다: " + createReq.getBaseHyperVer()));
// 신규 엔티티 생성 (기준 값 복사 후 변경된 값만 적용)
ModelHyperParamEntity entity = new ModelHyperParamEntity();
entity.setHyperVer(createReq.getNewHyperVer());
// Important
entity.setBackbone(
createReq.getBackbone() != null ? createReq.getBackbone() : baseEntity.getBackbone());
entity.setInputSize(
createReq.getInputSize() != null ? createReq.getInputSize() : baseEntity.getInputSize());
entity.setCropSize(
createReq.getCropSize() != null ? createReq.getCropSize() : baseEntity.getCropSize());
entity.setEpochCnt(
createReq.getEpochCnt() != null ? createReq.getEpochCnt() : baseEntity.getEpochCnt());
entity.setBatchSize(
createReq.getBatchSize() != null ? createReq.getBatchSize() : baseEntity.getBatchSize());
// Architecture
entity.setDropPathRate(
createReq.getDropPathRate() != null
? createReq.getDropPathRate()
: baseEntity.getDropPathRate());
entity.setFrozenStages(
createReq.getFrozenStages() != null
? createReq.getFrozenStages()
: baseEntity.getFrozenStages());
entity.setNeckPolicy(
createReq.getNeckPolicy() != null ? createReq.getNeckPolicy() : baseEntity.getNeckPolicy());
entity.setDecoderChannels(
createReq.getDecoderChannels() != null
? createReq.getDecoderChannels()
: baseEntity.getDecoderChannels());
entity.setClassWeight(
createReq.getClassWeight() != null
? createReq.getClassWeight()
: baseEntity.getClassWeight());
entity.setNumLayers(
createReq.getNumLayers() != null ? createReq.getNumLayers() : baseEntity.getNumLayers());
// Optimization
entity.setLearningRate(
createReq.getLearningRate() != null
? createReq.getLearningRate()
: baseEntity.getLearningRate());
entity.setWeightDecay(
createReq.getWeightDecay() != null
? createReq.getWeightDecay()
: baseEntity.getWeightDecay());
entity.setLayerDecayRate(
createReq.getLayerDecayRate() != null
? createReq.getLayerDecayRate()
: baseEntity.getLayerDecayRate());
entity.setDdpFindUnusedParams(
createReq.getDdpFindUnusedParams() != null
? createReq.getDdpFindUnusedParams()
: baseEntity.getDdpFindUnusedParams());
entity.setIgnoreIndex(
createReq.getIgnoreIndex() != null
? createReq.getIgnoreIndex()
: baseEntity.getIgnoreIndex());
// Data
entity.setTrainNumWorkers(
createReq.getTrainNumWorkers() != null
? createReq.getTrainNumWorkers()
: baseEntity.getTrainNumWorkers());
entity.setValNumWorkers(
createReq.getValNumWorkers() != null
? createReq.getValNumWorkers()
: baseEntity.getValNumWorkers());
entity.setTestNumWorkers(
createReq.getTestNumWorkers() != null
? createReq.getTestNumWorkers()
: baseEntity.getTestNumWorkers());
entity.setTrainShuffle(
createReq.getTrainShuffle() != null
? createReq.getTrainShuffle()
: baseEntity.getTrainShuffle());
entity.setTrainPersistent(
createReq.getTrainPersistent() != null
? createReq.getTrainPersistent()
: baseEntity.getTrainPersistent());
entity.setValPersistent(
createReq.getValPersistent() != null
? createReq.getValPersistent()
: baseEntity.getValPersistent());
// Evaluation
entity.setMetrics(
createReq.getMetrics() != null ? createReq.getMetrics() : baseEntity.getMetrics());
entity.setSaveBest(
createReq.getSaveBest() != null ? createReq.getSaveBest() : baseEntity.getSaveBest());
entity.setSaveBestRule(
createReq.getSaveBestRule() != null
? createReq.getSaveBestRule()
: baseEntity.getSaveBestRule());
entity.setValInterval(
createReq.getValInterval() != null
? createReq.getValInterval()
: baseEntity.getValInterval());
entity.setLogInterval(
createReq.getLogInterval() != null
? createReq.getLogInterval()
: baseEntity.getLogInterval());
entity.setVisInterval(
createReq.getVisInterval() != null
? createReq.getVisInterval()
: baseEntity.getVisInterval());
// Hardware
entity.setGpuCnt(
createReq.getGpuCnt() != null ? createReq.getGpuCnt() : baseEntity.getGpuCnt());
entity.setGpuIds(
createReq.getGpuIds() != null ? createReq.getGpuIds() : baseEntity.getGpuIds());
entity.setMasterPort(
createReq.getMasterPort() != null ? createReq.getMasterPort() : baseEntity.getMasterPort());
// Augmentation
entity.setRotProb(
createReq.getRotProb() != null ? createReq.getRotProb() : baseEntity.getRotProb());
entity.setFlipProb(
createReq.getFlipProb() != null ? createReq.getFlipProb() : baseEntity.getFlipProb());
entity.setRotDegree(
createReq.getRotDegree() != null ? createReq.getRotDegree() : baseEntity.getRotDegree());
entity.setExchangeProb(
createReq.getExchangeProb() != null
? createReq.getExchangeProb()
: baseEntity.getExchangeProb());
entity.setBrightnessDelta(
createReq.getBrightnessDelta() != null
? createReq.getBrightnessDelta()
: baseEntity.getBrightnessDelta());
entity.setContrastRange(
createReq.getContrastRange() != null
? createReq.getContrastRange()
: baseEntity.getContrastRange());
entity.setSaturationRange(
createReq.getSaturationRange() != null
? createReq.getSaturationRange()
: baseEntity.getSaturationRange());
entity.setHueDelta(
createReq.getHueDelta() != null ? createReq.getHueDelta() : baseEntity.getHueDelta());
// Legacy
entity.setDropoutRatio(
createReq.getDropoutRatio() != null
? createReq.getDropoutRatio()
: baseEntity.getDropoutRatio());
entity.setCnnFilterCnt(
createReq.getCnnFilterCnt() != null
? createReq.getCnnFilterCnt()
: baseEntity.getCnnFilterCnt());
// Common
entity.setMemo(createReq.getMemo());
entity.setDelYn("N");
entity.setCreatedDttm(ZonedDateTime.now());
ModelHyperParamEntity saved = hyperParamRepository.save(entity);
return saved.getHyperVer();
}
/**
* 하이퍼파라미터 단건 조회
*
* @param hyperVer 하이퍼파라미터 버전
* @return 하이퍼파라미터 정보
*/
public ModelMngDto.HyperParamInfo findByHyperVer(String hyperVer) {
ModelHyperParamEntity entity =
hyperParamRepository
.findById(hyperVer)
.orElseThrow(() -> new NotFoundException("하이퍼파라미터를 찾을 수 없습니다: " + hyperVer));
if ("Y".equals(entity.getDelYn())) {
throw new NotFoundException("삭제된 하이퍼파라미터입니다: " + hyperVer);
}
return mapToHyperParamInfo(entity);
}
/**
* 하이퍼파라미터 수정 (기존 버전은 수정 불가)
*
* @param hyperVer 하이퍼파라미터 버전
* @param updateReq 수정 요청
*/
public void updateHyperParam(String hyperVer, ModelMngDto.HyperParamCreateReq updateReq) {
// 기존 버전은 수정 불가
throw new BadRequestException("기존 버전은 수정할 수 없습니다. 신규 버전을 생성해주세요.");
}
/**
* 하이퍼파라미터 삭제 (논리 삭제)
*
* @param hyperVer 하이퍼파라미터 버전
*/
public void deleteHyperParam(String hyperVer) {
// H1은 디폴트 버전이므로 삭제 불가
if ("H1".equals(hyperVer)) {
throw new BadRequestException("H1은 디폴트 하이퍼파라미터 버전이므로 삭제할 수 없습니다.");
}
ModelHyperParamEntity entity =
hyperParamRepository
.findById(hyperVer)
.orElseThrow(() -> new NotFoundException("하이퍼파라미터를 찾을 수 없습니다: " + hyperVer));
if ("Y".equals(entity.getDelYn())) {
throw new BadRequestException("이미 삭제된 하이퍼파라미터입니다: " + hyperVer);
}
// 논리 삭제 처리
entity.setDelYn("Y");
hyperParamRepository.save(entity);
}
/**
* 첫 번째 하이퍼파라미터 버전 조회 (H1 확인용)
*
* @return 첫 번째 하이퍼파라미터 버전
*/
public String getFirstHyperParamVersion() {
List<ModelHyperParamEntity> entities =
hyperParamRepository.findByDelYnOrderByCreatedDttmDesc("N");
if (entities.isEmpty()) {
throw new NotFoundException("하이퍼파라미터가 존재하지 않습니다.");
}
// 가장 오래된 것이 H1이므로 리스트의 마지막 요소 반환
return entities.get(entities.size() - 1).getHyperVer();
}
}

View File

@@ -1,72 +1,72 @@
package com.kamco.cd.training.postgres.core;
import com.kamco.cd.training.common.exception.NotFoundException;
import com.kamco.cd.training.common.service.BaseCoreService;
import com.kamco.cd.training.dataset.dto.MapSheetDto;
import com.kamco.cd.training.postgres.entity.MapSheetEntity;
import com.kamco.cd.training.postgres.repository.dataset.MapSheetRepository;
import java.util.Optional;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
public class MapSheetCoreService
implements BaseCoreService<MapSheetDto.Basic, Long, MapSheetDto.SearchReq> {
private final MapSheetRepository mapSheetRepository;
@Override
public void remove(Long id) {
Optional<MapSheetEntity> mapSheet = mapSheetRepository.findById(id);
if (mapSheet.isEmpty()) {
return;
}
MapSheetEntity entity = mapSheet.get();
entity.setDeleted(true);
mapSheetRepository.save(entity);
}
@Override
public MapSheetDto.Basic getOneById(Long id) {
MapSheetEntity entity =
mapSheetRepository
.findById(id)
.orElseThrow(() -> new NotFoundException("도엽을 찾을 수 없습니다. ID: " + id));
if (entity.getDeleted()) {
throw new NotFoundException("삭제된 도엽입니다. ID: " + id);
}
return entity.toDto();
}
@Override
public Page<MapSheetDto.Basic> search(MapSheetDto.SearchReq searchReq) {
Page<MapSheetEntity> entityPage = mapSheetRepository.findMapSheetList(searchReq);
return entityPage.map(MapSheetEntity::toDto);
}
/**
* 도엽 목록 조회
*
* @param searchReq 검색 조건
* @return 페이징 처리된 도엽 목록
*/
public Page<MapSheetDto.Basic> findMapSheetList(MapSheetDto.SearchReq searchReq) {
return search(searchReq);
}
/**
* 도엽 삭제 (다건)
*
* @param deleteReq 삭제 요청
*/
public void deleteMapSheets(MapSheetDto.DeleteReq deleteReq) {
for (Long id : deleteReq.getItemIds()) {
remove(id);
}
}
}
package com.kamco.cd.training.postgres.core;
import com.kamco.cd.training.common.exception.NotFoundException;
import com.kamco.cd.training.common.service.BaseCoreService;
import com.kamco.cd.training.dataset.dto.MapSheetDto;
import com.kamco.cd.training.postgres.entity.MapSheetEntity;
import com.kamco.cd.training.postgres.repository.dataset.MapSheetRepository;
import java.util.Optional;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
public class MapSheetCoreService
implements BaseCoreService<MapSheetDto.Basic, Long, MapSheetDto.SearchReq> {
private final MapSheetRepository mapSheetRepository;
@Override
public void remove(Long id) {
Optional<MapSheetEntity> mapSheet = mapSheetRepository.findById(id);
if (mapSheet.isEmpty()) {
return;
}
MapSheetEntity entity = mapSheet.get();
entity.setDeleted(true);
mapSheetRepository.save(entity);
}
@Override
public MapSheetDto.Basic getOneById(Long id) {
MapSheetEntity entity =
mapSheetRepository
.findById(id)
.orElseThrow(() -> new NotFoundException("도엽을 찾을 수 없습니다. ID: " + id));
if (entity.getDeleted()) {
throw new NotFoundException("삭제된 도엽입니다. ID: " + id);
}
return entity.toDto();
}
@Override
public Page<MapSheetDto.Basic> search(MapSheetDto.SearchReq searchReq) {
Page<MapSheetEntity> entityPage = mapSheetRepository.findMapSheetList(searchReq);
return entityPage.map(MapSheetEntity::toDto);
}
/**
* 도엽 목록 조회
*
* @param searchReq 검색 조건
* @return 페이징 처리된 도엽 목록
*/
public Page<MapSheetDto.Basic> findMapSheetList(MapSheetDto.SearchReq searchReq) {
return search(searchReq);
}
/**
* 도엽 삭제 (다건)
*
* @param deleteReq 삭제 요청
*/
public void deleteMapSheets(MapSheetDto.DeleteReq deleteReq) {
for (Long id : deleteReq.getItemIds()) {
remove(id);
}
}
}

View File

@@ -1,167 +1,168 @@
package com.kamco.cd.training.postgres.core;
import com.kamco.cd.training.auth.BCryptSaltGenerator;
import com.kamco.cd.training.common.enums.StatusType;
import com.kamco.cd.training.common.enums.error.AuthErrorCode;
import com.kamco.cd.training.common.exception.CustomApiException;
import com.kamco.cd.training.common.utils.CommonStringUtils;
import com.kamco.cd.training.common.utils.UserUtil;
import com.kamco.cd.training.members.dto.MembersDto;
import com.kamco.cd.training.members.dto.MembersDto.AddReq;
import com.kamco.cd.training.members.dto.MembersDto.Basic;
import com.kamco.cd.training.members.dto.SignInRequest;
import com.kamco.cd.training.members.exception.MemberException.DuplicateMemberException;
import com.kamco.cd.training.members.exception.MemberException.DuplicateMemberException.Field;
import com.kamco.cd.training.members.exception.MemberException.MemberNotFoundException;
import com.kamco.cd.training.postgres.entity.MemberEntity;
import com.kamco.cd.training.postgres.repository.members.MembersRepository;
import java.time.ZonedDateTime;
import java.util.UUID;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.mindrot.jbcrypt.BCrypt;
import org.springframework.data.domain.Page;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
public class MembersCoreService {
private final MembersRepository membersRepository;
private final UserUtil userUtil;
/**
* 관리자 계정 등록
*
* @param addReq
* @return
*/
public Long saveMembers(AddReq addReq) {
if (membersRepository.existsByEmployeeNo(addReq.getEmployeeNo())) {
throw new DuplicateMemberException(Field.EMPLOYEE_NO, addReq.getEmployeeNo());
}
// salt 생성, 사번이 salt
String salt = BCryptSaltGenerator.generateSaltWithEmployeeNo(addReq.getEmployeeNo().trim());
// 패스워드 암호화, 초기 패스워드 고정
String hashedPassword = BCrypt.hashpw(addReq.getPassword(), salt);
MemberEntity memberEntity = new MemberEntity();
memberEntity.setUserId(addReq.getEmployeeNo());
memberEntity.setUserRole(addReq.getUserRole());
memberEntity.setPassword(hashedPassword);
memberEntity.setName(addReq.getName());
memberEntity.setEmployeeNo(addReq.getEmployeeNo());
memberEntity.setRgstrUidl(userUtil.getId());
memberEntity.setStatus(StatusType.PENDING.getId());
return membersRepository.save(memberEntity).getId();
}
/**
* 관리자 계정 수정
*
* @param uuid
* @param updateReq
*/
public void updateMembers(UUID uuid, MembersDto.UpdateReq updateReq) {
MemberEntity memberEntity =
membersRepository.findByUUID(uuid).orElseThrow(MemberNotFoundException::new);
if (StringUtils.isNotBlank(updateReq.getName())) {
memberEntity.setName(updateReq.getName());
}
if (StringUtils.isNotBlank(updateReq.getStatus())) {
memberEntity.changeStatus(updateReq.getStatus());
}
if (StringUtils.isNotBlank(updateReq.getPassword())) {
// 패스워드 유효성 검사
if (!CommonStringUtils.isValidPassword(updateReq.getPassword())) {
throw new CustomApiException("WRONG_PASSWORD", HttpStatus.BAD_REQUEST);
}
String password =
CommonStringUtils.hashPassword(updateReq.getPassword(), memberEntity.getEmployeeNo());
memberEntity.setStatus(StatusType.PENDING.getId());
memberEntity.setLoginFailCount(0);
memberEntity.setPassword(password);
memberEntity.setPwdResetYn(true);
}
memberEntity.setUpdtrUid(userUtil.getId());
membersRepository.save(memberEntity);
}
/**
* 패스워드 변경
*
* @param id
*/
public void resetPassword(String id, MembersDto.InitReq initReq) {
MemberEntity memberEntity =
membersRepository.findByEmployeeNo(id).orElseThrow(() -> new MemberNotFoundException());
// 기존 패스워드 확인
if (!BCrypt.checkpw(initReq.getOldPassword(), memberEntity.getPassword())) {
throw new CustomApiException(AuthErrorCode.LOGIN_PASSWORD_MISMATCH);
}
String password =
CommonStringUtils.hashPassword(initReq.getOldPassword(), memberEntity.getEmployeeNo());
memberEntity.setPassword(password);
memberEntity.setStatus(StatusType.ACTIVE.getId());
memberEntity.setUpdatedDttm(ZonedDateTime.now());
memberEntity.setUpdtrUid(memberEntity.getId());
memberEntity.setPwdResetYn(false);
membersRepository.save(memberEntity);
}
//
/**
* 회원목록 조회
*
* @param searchReq
* @return
*/
public Page<Basic> findByMembers(MembersDto.SearchReq searchReq) {
Page<MemberEntity> entityPage = membersRepository.findByMembers(searchReq);
return entityPage.map(MemberEntity::toDto);
}
/**
* 사용자 상태 조회
*
* @param request
* @return
*/
public String getUserStatus(SignInRequest request) {
MemberEntity memberEntity =
membersRepository
.findByEmployeeNo(request.getUsername())
.orElseThrow(() -> new CustomApiException("LOGIN_ID_NOT_FOUND", HttpStatus.UNAUTHORIZED));
return memberEntity.getStatus();
}
/**
* 최초 로그인 저장 마지막 로그인 저장
*
* @param uuid
*/
public void saveLogin(UUID uuid) {
MemberEntity memberEntity =
membersRepository.findByUUID(uuid).orElseThrow(() -> new MemberNotFoundException());
if (memberEntity.getFirstLoginDttm() == null) {
memberEntity.setFirstLoginDttm(ZonedDateTime.now());
}
memberEntity.setLastLoginDttm(ZonedDateTime.now());
memberEntity.setLoginFailCount(0);
membersRepository.save(memberEntity);
}
}
package com.kamco.cd.training.postgres.core;
import com.kamco.cd.training.auth.BCryptSaltGenerator;
import com.kamco.cd.training.common.enums.StatusType;
import com.kamco.cd.training.common.enums.error.AuthErrorCode;
import com.kamco.cd.training.common.exception.CustomApiException;
import com.kamco.cd.training.common.utils.CommonStringUtils;
import com.kamco.cd.training.common.utils.UserUtil;
import com.kamco.cd.training.members.dto.MembersDto;
import com.kamco.cd.training.members.dto.MembersDto.AddReq;
import com.kamco.cd.training.members.dto.MembersDto.Basic;
import com.kamco.cd.training.members.dto.SignInRequest;
import com.kamco.cd.training.members.exception.MemberException.DuplicateMemberException;
import com.kamco.cd.training.members.exception.MemberException.DuplicateMemberException.Field;
import com.kamco.cd.training.members.exception.MemberException.MemberNotFoundException;
import com.kamco.cd.training.postgres.entity.MemberEntity;
import com.kamco.cd.training.postgres.repository.members.MembersRepository;
import java.time.ZonedDateTime;
import java.util.UUID;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.mindrot.jbcrypt.BCrypt;
import org.springframework.data.domain.Page;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
public class MembersCoreService {
private final MembersRepository membersRepository;
private final UserUtil userUtil;
/**
* 관리자 계정 등록
*
* @param addReq
* @return
*/
public Long saveMembers(AddReq addReq) {
if (membersRepository.existsByEmployeeNo(addReq.getEmployeeNo())) {
throw new DuplicateMemberException(Field.EMPLOYEE_NO, addReq.getEmployeeNo());
}
// salt 생성, 사번이 salt
String salt = BCryptSaltGenerator.generateSaltWithEmployeeNo(addReq.getEmployeeNo().trim());
// 패스워드 암호화, 초기 패스워드 고정
String hashedPassword = BCrypt.hashpw(addReq.getPassword(), salt);
MemberEntity memberEntity = new MemberEntity();
memberEntity.setUserId(addReq.getEmployeeNo());
memberEntity.setUserRole(addReq.getUserRole());
memberEntity.setPassword(hashedPassword);
memberEntity.setName(addReq.getName());
memberEntity.setEmployeeNo(addReq.getEmployeeNo());
memberEntity.setRgstrUidl(userUtil.getId());
memberEntity.setStatus(StatusType.PENDING.getId());
return membersRepository.save(memberEntity).getId();
}
/**
* 관리자 계정 수정
*
* @param uuid
* @param updateReq
*/
public void updateMembers(UUID uuid, MembersDto.UpdateReq updateReq) {
MemberEntity memberEntity =
membersRepository.findByUUID(uuid).orElseThrow(MemberNotFoundException::new);
if (StringUtils.isNotBlank(updateReq.getName())) {
memberEntity.setName(updateReq.getName());
}
if (StringUtils.isNotBlank(updateReq.getStatus())) {
memberEntity.changeStatus(updateReq.getStatus());
}
if (StringUtils.isNotBlank(updateReq.getPassword())) {
// 패스워드 유효성 검사
if (!CommonStringUtils.isValidPassword(updateReq.getPassword())) {
throw new CustomApiException("WRONG_PASSWORD", HttpStatus.BAD_REQUEST);
}
String password =
CommonStringUtils.hashPassword(updateReq.getPassword(), memberEntity.getEmployeeNo());
memberEntity.setStatus(StatusType.PENDING.getId());
memberEntity.setLoginFailCount(0);
memberEntity.setPassword(password);
memberEntity.setPwdResetYn(true);
}
memberEntity.setUpdtrUid(userUtil.getId());
membersRepository.save(memberEntity);
}
/**
* 패스워드 변경
*
* @param id
*/
public void resetPassword(String id, MembersDto.InitReq initReq) {
MemberEntity memberEntity =
membersRepository.findByEmployeeNo(id).orElseThrow(() -> new MemberNotFoundException());
// 기존 패스워드 확인
if (!BCrypt.checkpw(initReq.getOldPassword(), memberEntity.getPassword())) {
throw new CustomApiException(AuthErrorCode.LOGIN_PASSWORD_MISMATCH);
}
String password =
CommonStringUtils.hashPassword(initReq.getOldPassword(), memberEntity.getEmployeeNo());
memberEntity.setPassword(password);
memberEntity.setStatus(StatusType.ACTIVE.getId());
memberEntity.setUpdatedDttm(ZonedDateTime.now());
memberEntity.setUpdtrUid(memberEntity.getId());
memberEntity.setPwdResetYn(false);
membersRepository.save(memberEntity);
}
//
/**
* 회원목록 조회
*
* @param searchReq
* @return
*/
public Page<Basic> findByMembers(MembersDto.SearchReq searchReq) {
Page<MemberEntity> entityPage = membersRepository.findByMembers(searchReq);
return entityPage.map(MemberEntity::toDto);
}
/**
* 사용자 상태 조회
*
* @param request
* @return
*/
public String getUserStatus(SignInRequest request) {
MemberEntity memberEntity =
membersRepository
.findByEmployeeNo(request.getUsername())
.orElseThrow(
() -> new CustomApiException("LOGIN_ID_NOT_FOUND", HttpStatus.UNAUTHORIZED));
return memberEntity.getStatus();
}
/**
* 최초 로그인 저장 마지막 로그인 저장
*
* @param uuid
*/
public void saveLogin(UUID uuid) {
MemberEntity memberEntity =
membersRepository.findByUUID(uuid).orElseThrow(() -> new MemberNotFoundException());
if (memberEntity.getFirstLoginDttm() == null) {
memberEntity.setFirstLoginDttm(ZonedDateTime.now());
}
memberEntity.setLastLoginDttm(ZonedDateTime.now());
memberEntity.setLoginFailCount(0);
membersRepository.save(memberEntity);
}
}

View File

@@ -1,19 +1,19 @@
package com.kamco.cd.training.postgres.core;
import com.kamco.cd.training.menu.dto.MenuDto;
import com.kamco.cd.training.postgres.entity.MenuEntity;
import com.kamco.cd.training.postgres.repository.menu.MenuRepository;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
public class MenuCoreService {
private final MenuRepository menuRepository;
public List<MenuDto.Basic> getFindAll() {
return menuRepository.getFindAll().stream().map(MenuEntity::toDto).toList();
}
}
package com.kamco.cd.training.postgres.core;
import com.kamco.cd.training.menu.dto.MenuDto;
import com.kamco.cd.training.postgres.entity.MenuEntity;
import com.kamco.cd.training.postgres.repository.menu.MenuRepository;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
public class MenuCoreService {
private final MenuRepository menuRepository;
public List<MenuDto.Basic> getFindAll() {
return menuRepository.getFindAll().stream().map(MenuEntity::toDto).toList();
}
}

View File

@@ -1,202 +1,202 @@
package com.kamco.cd.training.postgres.core;
import com.kamco.cd.training.common.exception.BadRequestException;
import com.kamco.cd.training.common.exception.NotFoundException;
import com.kamco.cd.training.model.dto.ModelMngDto;
import com.kamco.cd.training.model.dto.ModelMngDto.Basic;
import com.kamco.cd.training.postgres.entity.ModelDatasetMappEntity;
import com.kamco.cd.training.postgres.entity.ModelTrainMasterEntity;
import com.kamco.cd.training.postgres.repository.model.ModelDatasetMappRepository;
import com.kamco.cd.training.postgres.repository.model.ModelMngRepository;
import java.time.ZonedDateTime;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
public class ModelMngCoreService {
private final ModelMngRepository modelMngRepository;
private final ModelDatasetMappRepository modelDatasetMappRepository;
/**
* 모델 목록 조회
*
* @param searchReq 검색 조건
* @return 페이징 처리된 모델 목록
*/
public Page<Basic> findByModels(ModelMngDto.SearchReq searchReq) {
Page<ModelTrainMasterEntity> entityPage = modelMngRepository.findByModels(searchReq);
return entityPage.map(ModelTrainMasterEntity::toDto);
}
/**
* 모델 상세 조회
*
* @param modelUid 모델 UID
* @return 모델 상세 정보
*/
public ModelMngDto.Detail getModelDetail(Long modelUid) {
ModelTrainMasterEntity entity =
modelMngRepository
.findById(modelUid)
.orElseThrow(() -> new NotFoundException("모델을 찾을 수 없습니다. ID: " + modelUid));
if (Boolean.TRUE.equals(entity.getDelYn())) {
throw new NotFoundException("삭제된 모델입니다. ID: " + modelUid);
}
return ModelMngDto.Detail.builder()
.uuid(entity.getUuid().toString())
.modelVer(entity.getModelVer())
.hyperVer(entity.getHyperVer())
.epochVer(entity.getEpochVer())
.processStep(entity.getProcessStep())
.statusCd(entity.getStatusCd())
.trainStartDttm(entity.getTrainStartDttm())
.epochCnt(entity.getEpochCnt())
.datasetRatio(entity.getDatasetRatio())
.bestEpoch(entity.getBestEpoch())
.confirmedBestEpoch(entity.getConfirmedBestEpoch())
.step1EndDttm(entity.getStep1EndDttm())
.step1Duration(entity.getStep1Duration())
.step2EndDttm(entity.getStep2EndDttm())
.step2Duration(entity.getStep2Duration())
.progressRate(entity.getProgressRate())
.createdDttm(entity.getCreatedDttm())
.updatedDttm(entity.getUpdatedDttm())
.modelPath(entity.getModelPath())
.errorMsg(entity.getErrorMsg())
.build();
}
/**
* 모델 상세 조회 (UUID 기반)
*
* @param uuid 모델 UUID
* @return 모델 상세 정보
*/
public ModelMngDto.Detail getModelDetailByUuid(String uuid) {
ModelTrainMasterEntity entity = findByUuid(uuid);
return getModelDetail(entity.getId());
}
/**
* 학습 모델 전체 목록 조회 (삭제되지 않은 것만)
*
* @return 학습 모델 목록
*/
public List<ModelMngDto.TrainListRes> findAllTrainModels() {
List<ModelTrainMasterEntity> entities =
modelMngRepository.findByDelYnOrderByCreatedDttmDesc(false);
return entities.stream()
.map(
entity ->
ModelMngDto.TrainListRes.builder()
.uuid(entity.getUuid().toString())
.modelVer(entity.getModelVer())
.status(entity.getStatusCd())
.processStep(entity.getProcessStep())
.trainStartDttm(entity.getTrainStartDttm())
.progressRate(entity.getProgressRate())
.epochCnt(entity.getEpochCnt())
.step1EndDttm(entity.getStep1EndDttm())
.step1Duration(entity.getStep1Duration())
.step2EndDttm(entity.getStep2EndDttm())
.step2Duration(entity.getStep2Duration())
.createdDttm(entity.getCreatedDttm())
.errorMsg(entity.getErrorMsg())
.canResume(entity.getCanResume())
.lastCheckpointEpoch(entity.getLastCheckpointEpoch())
.build())
.toList();
}
/**
* 현재 실행 중인 모델 확인
*
* @return 실행 중인 모델 UUID (없으면 null)
*/
public String findRunningModelUuid() {
return modelMngRepository
.findFirstByStatusCdAndDelYn("RUNNING", false)
.map(entity -> entity.getUuid().toString())
.orElse(null);
}
/**
* 학습 마스터 생성
*
* @param trainReq 학습 시작 요청
* @return 생성된 모델 Entity
*/
public ModelTrainMasterEntity createTrainMaster(ModelMngDto.TrainStartReq trainReq) {
ModelTrainMasterEntity entity = new ModelTrainMasterEntity();
entity.setModelVer(trainReq.getHyperVer());
entity.setHyperVer(trainReq.getHyperVer());
entity.setEpochVer(String.valueOf(trainReq.getEpoch()));
entity.setProcessStep("STEP1");
entity.setStatusCd("READY");
entity.setTrainStartDttm(ZonedDateTime.now());
entity.setEpochCnt(trainReq.getEpoch());
entity.setDatasetRatio(trainReq.getDatasetRatio());
entity.setDelYn(false);
entity.setCreatedDttm(ZonedDateTime.now());
entity.setProgressRate(0);
return modelMngRepository.save(entity);
}
/**
* 데이터셋 매핑 생성
*
* @param modelUid 모델 UID
* @param datasetIds 데이터셋 ID 목록
*/
public void createDatasetMappings(Long modelUid, List<Long> datasetIds) {
for (Long datasetId : datasetIds) {
ModelDatasetMappEntity mapping = new ModelDatasetMappEntity();
mapping.setModelUid(modelUid);
mapping.setDatasetUid(datasetId);
mapping.setDatasetType("TRAIN");
modelDatasetMappRepository.save(mapping);
}
}
/**
* UUID로 모델 조회
*
* @param uuid UUID
* @return 모델 Entity
*/
public ModelTrainMasterEntity findByUuid(String uuid) {
try {
java.util.UUID uuidObj = java.util.UUID.fromString(uuid);
return modelMngRepository
.findByUuid(uuidObj)
.orElseThrow(() -> new NotFoundException("모델을 찾을 수 없습니다. UUID: " + uuid));
} catch (IllegalArgumentException e) {
throw new BadRequestException("잘못된 UUID 형식입니다: " + uuid);
}
}
/**
* 모델 삭제 (논리 삭제)
*
* @param uuid UUID
*/
public void deleteByUuid(String uuid) {
ModelTrainMasterEntity entity = findByUuid(uuid);
// 진행 중인 모델은 삭제 불가
if ("RUNNING".equals(entity.getStatusCd())) {
throw new BadRequestException("진행 중인 모델은 삭제할 수 없습니다.");
}
entity.setDelYn(true);
entity.setUpdatedDttm(ZonedDateTime.now());
modelMngRepository.save(entity);
}
}
package com.kamco.cd.training.postgres.core;
import com.kamco.cd.training.common.exception.BadRequestException;
import com.kamco.cd.training.common.exception.NotFoundException;
import com.kamco.cd.training.model.dto.ModelMngDto;
import com.kamco.cd.training.model.dto.ModelMngDto.Basic;
import com.kamco.cd.training.postgres.entity.ModelDatasetMappEntity;
import com.kamco.cd.training.postgres.entity.ModelTrainMasterEntity;
import com.kamco.cd.training.postgres.repository.model.ModelDatasetMappRepository;
import com.kamco.cd.training.postgres.repository.model.ModelMngRepository;
import java.time.ZonedDateTime;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
public class ModelMngCoreService {
private final ModelMngRepository modelMngRepository;
private final ModelDatasetMappRepository modelDatasetMappRepository;
/**
* 모델 목록 조회
*
* @param searchReq 검색 조건
* @return 페이징 처리된 모델 목록
*/
public Page<Basic> findByModels(ModelMngDto.SearchReq searchReq) {
Page<ModelTrainMasterEntity> entityPage = modelMngRepository.findByModels(searchReq);
return entityPage.map(ModelTrainMasterEntity::toDto);
}
/**
* 모델 상세 조회
*
* @param modelUid 모델 UID
* @return 모델 상세 정보
*/
public ModelMngDto.Detail getModelDetail(Long modelUid) {
ModelTrainMasterEntity entity =
modelMngRepository
.findById(modelUid)
.orElseThrow(() -> new NotFoundException("모델을 찾을 수 없습니다. ID: " + modelUid));
if (Boolean.TRUE.equals(entity.getDelYn())) {
throw new NotFoundException("삭제된 모델입니다. ID: " + modelUid);
}
return ModelMngDto.Detail.builder()
.uuid(entity.getUuid().toString())
.modelVer(entity.getModelVer())
.hyperVer(entity.getHyperVer())
.epochVer(entity.getEpochVer())
.processStep(entity.getProcessStep())
.statusCd(entity.getStatusCd())
.trainStartDttm(entity.getTrainStartDttm())
.epochCnt(entity.getEpochCnt())
.datasetRatio(entity.getDatasetRatio())
.bestEpoch(entity.getBestEpoch())
.confirmedBestEpoch(entity.getConfirmedBestEpoch())
.step1EndDttm(entity.getStep1EndDttm())
.step1Duration(entity.getStep1Duration())
.step2EndDttm(entity.getStep2EndDttm())
.step2Duration(entity.getStep2Duration())
.progressRate(entity.getProgressRate())
.createdDttm(entity.getCreatedDttm())
.updatedDttm(entity.getUpdatedDttm())
.modelPath(entity.getModelPath())
.errorMsg(entity.getErrorMsg())
.build();
}
/**
* 모델 상세 조회 (UUID 기반)
*
* @param uuid 모델 UUID
* @return 모델 상세 정보
*/
public ModelMngDto.Detail getModelDetailByUuid(String uuid) {
ModelTrainMasterEntity entity = findByUuid(uuid);
return getModelDetail(entity.getId());
}
/**
* 학습 모델 전체 목록 조회 (삭제되지 않은 것만)
*
* @return 학습 모델 목록
*/
public List<ModelMngDto.TrainListRes> findAllTrainModels() {
List<ModelTrainMasterEntity> entities =
modelMngRepository.findByDelYnOrderByCreatedDttmDesc(false);
return entities.stream()
.map(
entity ->
ModelMngDto.TrainListRes.builder()
.uuid(entity.getUuid().toString())
.modelVer(entity.getModelVer())
.status(entity.getStatusCd())
.processStep(entity.getProcessStep())
.trainStartDttm(entity.getTrainStartDttm())
.progressRate(entity.getProgressRate())
.epochCnt(entity.getEpochCnt())
.step1EndDttm(entity.getStep1EndDttm())
.step1Duration(entity.getStep1Duration())
.step2EndDttm(entity.getStep2EndDttm())
.step2Duration(entity.getStep2Duration())
.createdDttm(entity.getCreatedDttm())
.errorMsg(entity.getErrorMsg())
.canResume(entity.getCanResume())
.lastCheckpointEpoch(entity.getLastCheckpointEpoch())
.build())
.toList();
}
/**
* 현재 실행 중인 모델 확인
*
* @return 실행 중인 모델 UUID (없으면 null)
*/
public String findRunningModelUuid() {
return modelMngRepository
.findFirstByStatusCdAndDelYn("RUNNING", false)
.map(entity -> entity.getUuid().toString())
.orElse(null);
}
/**
* 학습 마스터 생성
*
* @param trainReq 학습 시작 요청
* @return 생성된 모델 Entity
*/
public ModelTrainMasterEntity createTrainMaster(ModelMngDto.TrainStartReq trainReq) {
ModelTrainMasterEntity entity = new ModelTrainMasterEntity();
entity.setModelVer(trainReq.getHyperVer());
entity.setHyperVer(trainReq.getHyperVer());
entity.setEpochVer(String.valueOf(trainReq.getEpoch()));
entity.setProcessStep("STEP1");
entity.setStatusCd("READY");
entity.setTrainStartDttm(ZonedDateTime.now());
entity.setEpochCnt(trainReq.getEpoch());
entity.setDatasetRatio(trainReq.getDatasetRatio());
entity.setDelYn(false);
entity.setCreatedDttm(ZonedDateTime.now());
entity.setProgressRate(0);
return modelMngRepository.save(entity);
}
/**
* 데이터셋 매핑 생성
*
* @param modelUid 모델 UID
* @param datasetIds 데이터셋 ID 목록
*/
public void createDatasetMappings(Long modelUid, List<Long> datasetIds) {
for (Long datasetId : datasetIds) {
ModelDatasetMappEntity mapping = new ModelDatasetMappEntity();
mapping.setModelUid(modelUid);
mapping.setDatasetUid(datasetId);
mapping.setDatasetType("TRAIN");
modelDatasetMappRepository.save(mapping);
}
}
/**
* UUID로 모델 조회
*
* @param uuid UUID
* @return 모델 Entity
*/
public ModelTrainMasterEntity findByUuid(String uuid) {
try {
java.util.UUID uuidObj = java.util.UUID.fromString(uuid);
return modelMngRepository
.findByUuid(uuidObj)
.orElseThrow(() -> new NotFoundException("모델을 찾을 수 없습니다. UUID: " + uuid));
} catch (IllegalArgumentException e) {
throw new BadRequestException("잘못된 UUID 형식입니다: " + uuid);
}
}
/**
* 모델 삭제 (논리 삭제)
*
* @param uuid UUID
*/
public void deleteByUuid(String uuid) {
ModelTrainMasterEntity entity = findByUuid(uuid);
// 진행 중인 모델은 삭제 불가
if ("RUNNING".equals(entity.getStatusCd())) {
throw new BadRequestException("진행 중인 모델은 삭제할 수 없습니다.");
}
entity.setDelYn(true);
entity.setUpdatedDttm(ZonedDateTime.now());
modelMngRepository.save(entity);
}
}

View File

@@ -1,66 +1,66 @@
package com.kamco.cd.training.postgres.core;
import com.kamco.cd.training.postgres.entity.SystemMetricsEntity;
import com.kamco.cd.training.postgres.repository.SystemMetricsRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
@Slf4j
public class SystemMetricsCoreService {
private final SystemMetricsRepository systemMetricsRepository;
/**
* 현재 사용 가능한 저장공간 조회 (MB 단위)
*
* @return 사용 가능한 저장공간 (MB)
*/
public long getAvailableStorageMB() {
SystemMetricsEntity latestMetrics =
systemMetricsRepository
.findLatestMetrics()
.orElseThrow(() -> new IllegalStateException("시스템 메트릭 정보를 조회할 수 없습니다"));
Long kbmemfree = latestMetrics.getKbmemfree();
Long kbmemused = latestMetrics.getKbmemused();
if (kbmemfree == null || kbmemused == null) {
log.warn("시스템 메트릭에 메모리 정보가 없습니다");
return 0L;
}
// 남은 용량 = kbmemfree - kbmemused (KB 단위)
long availableKB = kbmemfree - kbmemused;
// KB를 MB로 변환
long availableMB = availableKB / 1024;
log.info(
"사용 가능한 저장공간: {}MB (kbmemfree: {}KB, kbmemused: {}KB)", availableMB, kbmemfree, kbmemused);
return Math.max(0L, availableMB);
}
/**
* 학습 실행 가능 여부 확인 (10GB 이상 필요)
*
* @return 학습 실행 가능 여부
*/
public boolean isStorageAvailableForTraining() {
long availableMB = getAvailableStorageMB();
long requiredMB = 10 * 1024; // 10GB = 10,240MB
boolean isAvailable = availableMB >= requiredMB;
if (!isAvailable) {
log.warn("저장공간 부족: 현재 {}MB, 필요 {}MB", availableMB, requiredMB);
}
return isAvailable;
}
}
package com.kamco.cd.training.postgres.core;
import com.kamco.cd.training.postgres.entity.SystemMetricsEntity;
import com.kamco.cd.training.postgres.repository.SystemMetricsRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
@Slf4j
public class SystemMetricsCoreService {
private final SystemMetricsRepository systemMetricsRepository;
/**
* 현재 사용 가능한 저장공간 조회 (MB 단위)
*
* @return 사용 가능한 저장공간 (MB)
*/
public long getAvailableStorageMB() {
SystemMetricsEntity latestMetrics =
systemMetricsRepository
.findLatestMetrics()
.orElseThrow(() -> new IllegalStateException("시스템 메트릭 정보를 조회할 수 없습니다"));
Long kbmemfree = latestMetrics.getKbmemfree();
Long kbmemused = latestMetrics.getKbmemused();
if (kbmemfree == null || kbmemused == null) {
log.warn("시스템 메트릭에 메모리 정보가 없습니다");
return 0L;
}
// 남은 용량 = kbmemfree - kbmemused (KB 단위)
long availableKB = kbmemfree - kbmemused;
// KB를 MB로 변환
long availableMB = availableKB / 1024;
log.info(
"사용 가능한 저장공간: {}MB (kbmemfree: {}KB, kbmemused: {}KB)", availableMB, kbmemfree, kbmemused);
return Math.max(0L, availableMB);
}
/**
* 학습 실행 가능 여부 확인 (10GB 이상 필요)
*
* @return 학습 실행 가능 여부
*/
public boolean isStorageAvailableForTraining() {
long availableMB = getAvailableStorageMB();
long requiredMB = 10 * 1024; // 10GB = 10,240MB
boolean isAvailable = availableMB >= requiredMB;
if (!isAvailable) {
log.warn("저장공간 부족: 현재 {}MB, 필요 {}MB", availableMB, requiredMB);
}
return isAvailable;
}
}

View File

@@ -1,57 +1,57 @@
package com.kamco.cd.training.postgres.core;
import com.kamco.cd.training.common.enums.error.AuthErrorCode;
import com.kamco.cd.training.common.exception.CustomApiException;
import com.kamco.cd.training.postgres.entity.AuthRefreshTokenEntity;
import com.kamco.cd.training.postgres.repository.members.AuthRefreshTokenRepository;
import java.time.ZonedDateTime;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
public class TokenCoreService {
private final AuthRefreshTokenRepository tokenRepository;
public void save(String subject, String refreshToken, long validityMs) {
ZonedDateTime expiresAt = ZonedDateTime.now().plusSeconds(validityMs / 1000);
tokenRepository
.findBySubject(subject)
.ifPresentOrElse(
entity -> entity.rotate(refreshToken, expiresAt),
() ->
tokenRepository.save(new AuthRefreshTokenEntity(subject, refreshToken, expiresAt)));
}
/**
* refreshToken을 DB와 비교 검증
*
* @param subject 사용자 식별(UUID)
* @return
*/
public String getValidTokenOrThrow(String subject) {
// DB 기준 유효한 RefreshToken 문자열 반환 (없으면 401 예외)
return tokenRepository
.findBySubjectAndRevokedDttmIsNullAndExpiresDttmAfter(subject, ZonedDateTime.now())
.orElseThrow(() -> new CustomApiException(AuthErrorCode.REFRESH_TOKEN_EXPIRED_OR_REVOKED))
.getToken();
}
/**
* 로그아웃
*
* @param subject
*/
public void revokeBySubject(String subject) {
AuthRefreshTokenEntity token =
tokenRepository
.findBySubjectAndRevokedDttmIsNullAndExpiresDttmAfter(subject, ZonedDateTime.now())
.orElseThrow(() -> new CustomApiException(AuthErrorCode.REFRESH_TOKEN_MISMATCH));
// save() 호출 안 해도 됨 (영속 상태 + 트랜잭션)
token.revoke();
}
}
package com.kamco.cd.training.postgres.core;
import com.kamco.cd.training.common.enums.error.AuthErrorCode;
import com.kamco.cd.training.common.exception.CustomApiException;
import com.kamco.cd.training.postgres.entity.AuthRefreshTokenEntity;
import com.kamco.cd.training.postgres.repository.members.AuthRefreshTokenRepository;
import java.time.ZonedDateTime;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
public class TokenCoreService {
private final AuthRefreshTokenRepository tokenRepository;
public void save(String subject, String refreshToken, long validityMs) {
ZonedDateTime expiresAt = ZonedDateTime.now().plusSeconds(validityMs / 1000);
tokenRepository
.findBySubject(subject)
.ifPresentOrElse(
entity -> entity.rotate(refreshToken, expiresAt),
() ->
tokenRepository.save(new AuthRefreshTokenEntity(subject, refreshToken, expiresAt)));
}
/**
* refreshToken을 DB와 비교 검증
*
* @param subject 사용자 식별(UUID)
* @return
*/
public String getValidTokenOrThrow(String subject) {
// DB 기준 유효한 RefreshToken 문자열 반환 (없으면 401 예외)
return tokenRepository
.findBySubjectAndRevokedDttmIsNullAndExpiresDttmAfter(subject, ZonedDateTime.now())
.orElseThrow(() -> new CustomApiException(AuthErrorCode.REFRESH_TOKEN_EXPIRED_OR_REVOKED))
.getToken();
}
/**
* 로그아웃
*
* @param subject
*/
public void revokeBySubject(String subject) {
AuthRefreshTokenEntity token =
tokenRepository
.findBySubjectAndRevokedDttmIsNullAndExpiresDttmAfter(subject, ZonedDateTime.now())
.orElseThrow(() -> new CustomApiException(AuthErrorCode.REFRESH_TOKEN_MISMATCH));
// save() 호출 안 해도 됨 (영속 상태 + 트랜잭션)
token.revoke();
}
}

View File

@@ -1,57 +1,53 @@
package com.kamco.cd.training.postgres.core;
import com.kamco.cd.training.postgres.entity.UploadSessionEntity;
import com.kamco.cd.training.postgres.repository.upload.UploadSessionRepository;
import com.kamco.cd.training.upload.dto.UploadDto;
import java.util.UUID;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
public class UploadSessionCoreService {
private final UploadSessionRepository uploadSessionRepository;
public void createUploadSession(UploadDto.UploadAddReq addReq)
{
/*
UUID newUuid = UUID.randomUUID();
UploadSessionEntity entity = new UploadSessionEntity();
entity.setUploadId(addReq.getUploadId());
entity.setDatasetId(addReq.getDatasetId());
entity.setFileName(addReq.getFileName());
entity.setFileSize(addReq.getFileSize());
entity.setFinalPath(addReq.getFinalPath());
entity.setStatus(addReq.getStatus());
entity.setTempPath(addReq.getTempPath());
entity.setChunkIndex(addReq.getChunkIndex());
entity.setChunkTotalIndex(addReq.getChunkTotalIndex());
entity.setUploadDivi(addReq.getUploadDivi());
entity.setFileHash(addReq.getFileHash());
entity.setUuid(newUuid);
//System.out.println("======================");
UploadSessionEntity saved = uploadSessionRepository.save(entity);
return String.valueOf(saved.getUuid());
*/
uploadSessionRepository.insertUploadSession(addReq);
}
public UploadDto.uploadDto findByDatasetUid(Long datasetId, String uploadDivi){
return uploadSessionRepository.findByDatasetUid(datasetId, uploadDivi);
}
public UploadDto.uploadDto findByUuid(String uuid){
return uploadSessionRepository.findByUuid(uuid);
}
public void updateUploadSessionStatus(UploadDto.UploadAddReq addReq){
uploadSessionRepository.updateUploadSessionStatus(addReq);
}
}
package com.kamco.cd.training.postgres.core;
import com.kamco.cd.training.postgres.repository.upload.UploadSessionRepository;
import com.kamco.cd.training.upload.dto.UploadDto;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
public class UploadSessionCoreService {
private final UploadSessionRepository uploadSessionRepository;
public void createUploadSession(UploadDto.UploadAddReq addReq) {
/*
UUID newUuid = UUID.randomUUID();
UploadSessionEntity entity = new UploadSessionEntity();
entity.setUploadId(addReq.getUploadId());
entity.setDatasetId(addReq.getDatasetId());
entity.setFileName(addReq.getFileName());
entity.setFileSize(addReq.getFileSize());
entity.setFinalPath(addReq.getFinalPath());
entity.setStatus(addReq.getStatus());
entity.setTempPath(addReq.getTempPath());
entity.setChunkIndex(addReq.getChunkIndex());
entity.setChunkTotalIndex(addReq.getChunkTotalIndex());
entity.setUploadDivi(addReq.getUploadDivi());
entity.setFileHash(addReq.getFileHash());
entity.setUuid(newUuid);
//System.out.println("======================");
UploadSessionEntity saved = uploadSessionRepository.save(entity);
return String.valueOf(saved.getUuid());
*/
uploadSessionRepository.insertUploadSession(addReq);
}
public UploadDto.uploadDto findByDatasetUid(Long datasetId, String uploadDivi) {
return uploadSessionRepository.findByDatasetUid(datasetId, uploadDivi);
}
public UploadDto.uploadDto findByUuid(String uuid) {
return uploadSessionRepository.findByUuid(uuid);
}
public void updateUploadSessionStatus(UploadDto.UploadAddReq addReq) {
uploadSessionRepository.updateUploadSessionStatus(addReq);
}
}

View File

@@ -1,101 +1,101 @@
package com.kamco.cd.training.postgres.entity;
import com.kamco.cd.training.log.dto.AuditLogDto;
import com.kamco.cd.training.log.dto.EventStatus;
import com.kamco.cd.training.log.dto.EventType;
import com.kamco.cd.training.postgres.CommonCreateEntity;
import jakarta.persistence.*;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Table(name = "tb_audit_log")
public class AuditLogEntity extends CommonCreateEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "audit_log_uid", nullable = false)
private Long id;
@Column(name = "user_uid")
private Long userUid;
@Enumerated(EnumType.STRING)
private EventType eventType;
@Enumerated(EnumType.STRING)
private EventStatus eventStatus;
@Column(name = "menu_uid")
private String menuUid;
@Column(name = "ip_address")
private String ipAddress;
@Column(name = "request_uri")
private String requestUri;
@Column(name = "request_body", columnDefinition = "TEXT")
private String requestBody;
@Column(name = "error_log_uid")
private Long errorLogUid;
public AuditLogEntity(
Long userUid,
EventType eventType,
EventStatus eventStatus,
String menuUid,
String ipAddress,
String requestUri,
String requestBody,
Long errorLogUid) {
this.userUid = userUid;
this.eventType = eventType;
this.eventStatus = eventStatus;
this.menuUid = menuUid;
this.ipAddress = ipAddress;
this.requestUri = requestUri;
this.requestBody = requestBody;
this.errorLogUid = errorLogUid;
}
public AuditLogDto.Basic toDto() {
return new AuditLogDto.Basic(
this.id,
this.userUid,
this.eventType,
this.eventStatus,
this.menuUid,
this.ipAddress,
this.requestUri,
this.requestBody,
this.errorLogUid,
super.getCreatedDate());
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(this.id)
.append("\n")
.append(this.userUid)
.append("\n")
.append(this.eventType)
.append("\n")
.append(this.eventStatus)
.append("\n")
.append(this.menuUid)
.append("\n")
.append(this.ipAddress)
.append("\n")
.append(this.requestUri)
.append("\n")
.append(this.requestBody)
.append("\n")
.append(this.errorLogUid);
return sb.toString();
}
}
package com.kamco.cd.training.postgres.entity;
import com.kamco.cd.training.log.dto.AuditLogDto;
import com.kamco.cd.training.log.dto.EventStatus;
import com.kamco.cd.training.log.dto.EventType;
import com.kamco.cd.training.postgres.CommonCreateEntity;
import jakarta.persistence.*;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Table(name = "tb_audit_log")
public class AuditLogEntity extends CommonCreateEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "audit_log_uid", nullable = false)
private Long id;
@Column(name = "user_uid")
private Long userUid;
@Enumerated(EnumType.STRING)
private EventType eventType;
@Enumerated(EnumType.STRING)
private EventStatus eventStatus;
@Column(name = "menu_uid")
private String menuUid;
@Column(name = "ip_address")
private String ipAddress;
@Column(name = "request_uri")
private String requestUri;
@Column(name = "request_body", columnDefinition = "TEXT")
private String requestBody;
@Column(name = "error_log_uid")
private Long errorLogUid;
public AuditLogEntity(
Long userUid,
EventType eventType,
EventStatus eventStatus,
String menuUid,
String ipAddress,
String requestUri,
String requestBody,
Long errorLogUid) {
this.userUid = userUid;
this.eventType = eventType;
this.eventStatus = eventStatus;
this.menuUid = menuUid;
this.ipAddress = ipAddress;
this.requestUri = requestUri;
this.requestBody = requestBody;
this.errorLogUid = errorLogUid;
}
public AuditLogDto.Basic toDto() {
return new AuditLogDto.Basic(
this.id,
this.userUid,
this.eventType,
this.eventStatus,
this.menuUid,
this.ipAddress,
this.requestUri,
this.requestBody,
this.errorLogUid,
super.getCreatedDate());
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(this.id)
.append("\n")
.append(this.userUid)
.append("\n")
.append(this.eventType)
.append("\n")
.append(this.eventStatus)
.append("\n")
.append(this.menuUid)
.append("\n")
.append(this.ipAddress)
.append("\n")
.append(this.requestUri)
.append("\n")
.append(this.requestBody)
.append("\n")
.append(this.errorLogUid);
return sb.toString();
}
}

View File

@@ -1,67 +1,67 @@
package com.kamco.cd.training.postgres.entity;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import java.time.ZonedDateTime;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;
@Getter
@Setter
@Entity
@Table(name = "auth_refresh_token")
@NoArgsConstructor
public class AuthRefreshTokenEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", nullable = false)
private Long id;
@Size(max = 255)
@NotNull
@Column(name = "subject", nullable = false)
private String subject;
@NotNull
@Column(name = "token", nullable = false, length = Integer.MAX_VALUE)
private String token;
@NotNull
@Column(name = "expires_dttm", nullable = false)
private ZonedDateTime expiresDttm;
@Column(name = "revoked_dttm")
private ZonedDateTime revokedDttm;
@CreationTimestamp
@Column(updatable = false)
private ZonedDateTime createdDttm;
@UpdateTimestamp private ZonedDateTime updatedDttm;
public AuthRefreshTokenEntity(String subject, String token, ZonedDateTime expiresDttm) {
this.subject = subject;
this.token = token;
this.expiresDttm = expiresDttm;
}
public void rotate(String token, ZonedDateTime expiresDttm) {
this.token = token;
this.expiresDttm = expiresDttm;
this.revokedDttm = null;
}
public void revoke() {
this.revokedDttm = ZonedDateTime.now();
}
}
package com.kamco.cd.training.postgres.entity;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import java.time.ZonedDateTime;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;
@Getter
@Setter
@Entity
@Table(name = "auth_refresh_token")
@NoArgsConstructor
public class AuthRefreshTokenEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", nullable = false)
private Long id;
@Size(max = 255)
@NotNull
@Column(name = "subject", nullable = false)
private String subject;
@NotNull
@Column(name = "token", nullable = false, length = Integer.MAX_VALUE)
private String token;
@NotNull
@Column(name = "expires_dttm", nullable = false)
private ZonedDateTime expiresDttm;
@Column(name = "revoked_dttm")
private ZonedDateTime revokedDttm;
@CreationTimestamp
@Column(updatable = false)
private ZonedDateTime createdDttm;
@UpdateTimestamp private ZonedDateTime updatedDttm;
public AuthRefreshTokenEntity(String subject, String token, ZonedDateTime expiresDttm) {
this.subject = subject;
this.token = token;
this.expiresDttm = expiresDttm;
}
public void rotate(String token, ZonedDateTime expiresDttm) {
this.token = token;
this.expiresDttm = expiresDttm;
this.revokedDttm = null;
}
public void revoke() {
this.revokedDttm = ZonedDateTime.now();
}
}

View File

@@ -1,135 +1,135 @@
package com.kamco.cd.training.postgres.entity;
import com.kamco.cd.training.code.dto.CommonCodeDto;
import com.kamco.cd.training.postgres.CommonDateEntity;
import jakarta.persistence.*;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.List;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.Where;
@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Table(name = "tb_cm_cd")
public class CommonCodeEntity extends CommonDateEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "code_id", nullable = false, updatable = false)
private Long id;
@Size(max = 255)
@Column(name = "code_cd", updatable = false)
private String code;
@Size(max = 255)
@Column(name = "cd_ct")
private String description;
@Size(max = 255)
@Column(name = "cd_nm")
private String name;
@Column(name = "cd_odr")
private Integer order;
@Column(name = "used")
private Boolean used;
@NotNull
@Column(name = "deleted", nullable = false)
private Boolean deleted = false;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "parent_id", updatable = false)
private CommonCodeEntity parent;
@OneToMany(mappedBy = "parent", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@Where(clause = "deleted = false or deleted is null")
private List<CommonCodeEntity> children = new ArrayList<>();
@Size(max = 255)
@Column(name = "props1")
private String props1;
@Size(max = 255)
@Column(name = "props2")
private String props2;
@Size(max = 255)
@Column(name = "props3")
private String props3;
@Column(name = "deleted_dttm")
private ZonedDateTime deletedDttm;
public CommonCodeEntity(
String code,
String name,
String description,
Integer order,
Boolean used,
String props1,
String props2,
String props3) {
this.code = code;
this.name = name;
this.description = description;
this.order = order;
this.used = used;
this.props1 = props1;
this.props2 = props2;
this.props3 = props3;
}
public CommonCodeDto.Basic toDto() {
return new CommonCodeDto.Basic(
this.id,
this.code,
this.description,
this.name,
this.order,
this.used,
this.deleted,
this.children.stream().map(CommonCodeEntity::toDto).toList(),
super.getCreatedDate(),
super.getModifiedDate(),
this.props1,
this.props2,
this.props3,
this.deletedDttm);
}
public void addParent(CommonCodeEntity parent) {
this.parent = parent;
}
public boolean isDeleted() {
return deleted;
}
public void deleted() {
this.deleted = true;
this.deletedDttm = ZonedDateTime.now();
}
public void updateOrder(int order) {
this.order = order;
}
public void update(
String name, String description, boolean used, String props1, String props2, String props3) {
this.name = name;
this.description = description;
this.used = used;
this.props1 = props1;
this.props2 = props2;
this.props3 = props3;
}
}
package com.kamco.cd.training.postgres.entity;
import com.kamco.cd.training.code.dto.CommonCodeDto;
import com.kamco.cd.training.postgres.CommonDateEntity;
import jakarta.persistence.*;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.List;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.Where;
@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Table(name = "tb_cm_cd")
public class CommonCodeEntity extends CommonDateEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "code_id", nullable = false, updatable = false)
private Long id;
@Size(max = 255)
@Column(name = "code_cd", updatable = false)
private String code;
@Size(max = 255)
@Column(name = "cd_ct")
private String description;
@Size(max = 255)
@Column(name = "cd_nm")
private String name;
@Column(name = "cd_odr")
private Integer order;
@Column(name = "used")
private Boolean used;
@NotNull
@Column(name = "deleted", nullable = false)
private Boolean deleted = false;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "parent_id", updatable = false)
private CommonCodeEntity parent;
@OneToMany(mappedBy = "parent", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@Where(clause = "deleted = false or deleted is null")
private List<CommonCodeEntity> children = new ArrayList<>();
@Size(max = 255)
@Column(name = "props1")
private String props1;
@Size(max = 255)
@Column(name = "props2")
private String props2;
@Size(max = 255)
@Column(name = "props3")
private String props3;
@Column(name = "deleted_dttm")
private ZonedDateTime deletedDttm;
public CommonCodeEntity(
String code,
String name,
String description,
Integer order,
Boolean used,
String props1,
String props2,
String props3) {
this.code = code;
this.name = name;
this.description = description;
this.order = order;
this.used = used;
this.props1 = props1;
this.props2 = props2;
this.props3 = props3;
}
public CommonCodeDto.Basic toDto() {
return new CommonCodeDto.Basic(
this.id,
this.code,
this.description,
this.name,
this.order,
this.used,
this.deleted,
this.children.stream().map(CommonCodeEntity::toDto).toList(),
super.getCreatedDate(),
super.getModifiedDate(),
this.props1,
this.props2,
this.props3,
this.deletedDttm);
}
public void addParent(CommonCodeEntity parent) {
this.parent = parent;
}
public boolean isDeleted() {
return deleted;
}
public void deleted() {
this.deleted = true;
this.deletedDttm = ZonedDateTime.now();
}
public void updateOrder(int order) {
this.order = order;
}
public void update(
String name, String description, boolean used, String props1, String props2, String props3) {
this.name = name;
this.description = description;
this.used = used;
this.props1 = props1;
this.props2 = props2;
this.props3 = props3;
}
}

View File

@@ -1,132 +1,132 @@
package com.kamco.cd.training.postgres.entity;
import com.kamco.cd.training.dataset.dto.DatasetDto;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import java.time.Instant;
import java.time.ZonedDateTime;
import java.util.Map;
import java.util.UUID;
import lombok.Getter;
import lombok.Setter;
import org.hibernate.annotations.ColumnDefault;
import org.hibernate.annotations.JdbcTypeCode;
import org.hibernate.type.SqlTypes;
@Getter
@Setter
@Entity
@Table(name = "tb_dataset")
public class DatasetEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "dataset_uid", nullable = false)
private Long id;
@Column(name = "uuid", nullable = false)
private UUID uuid;
@Size(max = 200)
@Column(name = "group_title", length = 200)
private String groupTitle;
@Size(max = 10)
@Column(name = "data_year", length = 10)
private String dataYear;
@Size(max = 50)
@ColumnDefault("'CREATE'")
@Column(name = "data_type", length = 50)
private String dataType;
@ColumnDefault("1")
@Column(name = "round_no")
private Long roundNo;
@ColumnDefault("0")
@Column(name = "total_size")
private Long totalSize;
@ColumnDefault("0")
@Column(name = "item_count")
private Long itemCount;
@Column(name = "memo", length = Integer.MAX_VALUE)
private String memo;
@Size(max = 20)
@ColumnDefault("'READY'")
@Column(name = "status", length = 20)
private String status;
@Size(max = 50)
@Column(name = "reg_user_id", length = 50)
private String regUserId;
@ColumnDefault("now()")
@Column(name = "reg_dttm")
private Instant regDttm;
@Column(name = "mod_dttm")
private Instant modDttm;
@Column(name = "id")
private Long id1;
@Size(max = 50)
@Column(name = "created_by", length = 50)
private String createdBy;
@NotNull
@ColumnDefault("now()")
@Column(name = "created_dttm", nullable = false)
private ZonedDateTime createdDttm;
@NotNull
@ColumnDefault("false")
@Column(name = "deleted", nullable = false)
private Boolean deleted = false;
@Size(max = 200)
@Column(name = "title", length = 200)
private String title;
@Column(name = "total_items")
private Long totalItems;
@Size(max = 50)
@Column(name = "updated_by", length = 50)
private String updatedBy;
@Column(name = "updated_dttm")
private ZonedDateTime updatedDttm;
@Size(max = 4)
@Column(name = "year", length = 4)
private String year;
@Column(name = "class_counts", columnDefinition = "jsonb")
@JdbcTypeCode(SqlTypes.JSON)
private Map<String, Integer> classCounts;
public DatasetDto.Basic toDto() {
return new DatasetDto.Basic(
this.id,
this.uuid,
this.groupTitle,
this.title,
this.roundNo,
this.totalSize,
this.memo,
this.createdDttm,
this.status,
this.deleted);
}
}
package com.kamco.cd.training.postgres.entity;
import com.kamco.cd.training.dataset.dto.DatasetDto;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import java.time.Instant;
import java.time.ZonedDateTime;
import java.util.Map;
import java.util.UUID;
import lombok.Getter;
import lombok.Setter;
import org.hibernate.annotations.ColumnDefault;
import org.hibernate.annotations.JdbcTypeCode;
import org.hibernate.type.SqlTypes;
@Getter
@Setter
@Entity
@Table(name = "tb_dataset")
public class DatasetEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "dataset_uid", nullable = false)
private Long id;
@Column(name = "uuid", nullable = false)
private UUID uuid;
@Size(max = 200)
@Column(name = "group_title", length = 200)
private String groupTitle;
@Size(max = 10)
@Column(name = "data_year", length = 10)
private String dataYear;
@Size(max = 50)
@ColumnDefault("'CREATE'")
@Column(name = "data_type", length = 50)
private String dataType;
@ColumnDefault("1")
@Column(name = "round_no")
private Long roundNo;
@ColumnDefault("0")
@Column(name = "total_size")
private Long totalSize;
@ColumnDefault("0")
@Column(name = "item_count")
private Long itemCount;
@Column(name = "memo", length = Integer.MAX_VALUE)
private String memo;
@Size(max = 20)
@ColumnDefault("'READY'")
@Column(name = "status", length = 20)
private String status;
@Size(max = 50)
@Column(name = "reg_user_id", length = 50)
private String regUserId;
@ColumnDefault("now()")
@Column(name = "reg_dttm")
private Instant regDttm;
@Column(name = "mod_dttm")
private Instant modDttm;
@Column(name = "id")
private Long id1;
@Size(max = 50)
@Column(name = "created_by", length = 50)
private String createdBy;
@NotNull
@ColumnDefault("now()")
@Column(name = "created_dttm", nullable = false)
private ZonedDateTime createdDttm;
@NotNull
@ColumnDefault("false")
@Column(name = "deleted", nullable = false)
private Boolean deleted = false;
@Size(max = 200)
@Column(name = "title", length = 200)
private String title;
@Column(name = "total_items")
private Long totalItems;
@Size(max = 50)
@Column(name = "updated_by", length = 50)
private String updatedBy;
@Column(name = "updated_dttm")
private ZonedDateTime updatedDttm;
@Size(max = 4)
@Column(name = "year", length = 4)
private String year;
@Column(name = "class_counts", columnDefinition = "jsonb")
@JdbcTypeCode(SqlTypes.JSON)
private Map<String, Integer> classCounts;
public DatasetDto.Basic toDto() {
return new DatasetDto.Basic(
this.id,
this.uuid,
this.groupTitle,
this.title,
this.roundNo,
this.totalSize,
this.memo,
this.createdDttm,
this.status,
this.deleted);
}
}

View File

@@ -1,61 +1,61 @@
package com.kamco.cd.training.postgres.entity;
import com.kamco.cd.training.log.dto.ErrorLogDto;
import com.kamco.cd.training.log.dto.EventType;
import com.kamco.cd.training.postgres.CommonCreateEntity;
import jakarta.persistence.*;
import jakarta.validation.constraints.Size;
import java.time.ZonedDateTime;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Table(name = "tb_error_log")
public class ErrorLogEntity extends CommonCreateEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "error_log_uid", nullable = false)
private Long id;
@Column(name = "request_id")
private String requestId;
@Column(name = "error_type")
@Enumerated(EnumType.STRING)
private EventType errorType;
@Enumerated(EnumType.STRING)
private ErrorLogDto.LogErrorLevel errorLevel;
private String errorCode;
private String errorMessage;
@Size(max = 255)
@Column(name = "stack_trace")
private String stackTrace;
private Long handlerUid;
private ZonedDateTime handledDttm;
public ErrorLogEntity(
String requestId,
EventType errorType,
ErrorLogDto.LogErrorLevel errorLevel,
String errorCode,
String errorMessage,
String stackTrace,
Long handlerUid,
ZonedDateTime handledDttm) {
this.requestId = requestId;
this.errorType = errorType;
this.errorLevel = errorLevel;
this.errorCode = errorCode;
this.errorMessage = errorMessage;
this.stackTrace = stackTrace;
this.handlerUid = handlerUid;
this.handledDttm = handledDttm;
}
}
package com.kamco.cd.training.postgres.entity;
import com.kamco.cd.training.log.dto.ErrorLogDto;
import com.kamco.cd.training.log.dto.EventType;
import com.kamco.cd.training.postgres.CommonCreateEntity;
import jakarta.persistence.*;
import jakarta.validation.constraints.Size;
import java.time.ZonedDateTime;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Table(name = "tb_error_log")
public class ErrorLogEntity extends CommonCreateEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "error_log_uid", nullable = false)
private Long id;
@Column(name = "request_id")
private String requestId;
@Column(name = "error_type")
@Enumerated(EnumType.STRING)
private EventType errorType;
@Enumerated(EnumType.STRING)
private ErrorLogDto.LogErrorLevel errorLevel;
private String errorCode;
private String errorMessage;
@Size(max = 255)
@Column(name = "stack_trace")
private String stackTrace;
private Long handlerUid;
private ZonedDateTime handledDttm;
public ErrorLogEntity(
String requestId,
EventType errorType,
ErrorLogDto.LogErrorLevel errorLevel,
String errorCode,
String errorMessage,
String stackTrace,
Long handlerUid,
ZonedDateTime handledDttm) {
this.requestId = requestId;
this.errorType = errorType;
this.errorLevel = errorLevel;
this.errorCode = errorCode;
this.errorMessage = errorMessage;
this.stackTrace = stackTrace;
this.handlerUid = handlerUid;
this.handledDttm = handledDttm;
}
}

View File

@@ -1,80 +1,80 @@
package com.kamco.cd.training.postgres.entity;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.PrePersist;
import jakarta.persistence.PreUpdate;
import jakarta.persistence.Table;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import java.time.ZonedDateTime;
import lombok.Getter;
import lombok.Setter;
import org.hibernate.annotations.ColumnDefault;
@Getter
@Setter
@Entity
@Table(name = "tb_learn_data")
public class LearnDataEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", nullable = false)
private Long id;
@Size(max = 50)
@NotNull
@Column(name = "category", nullable = false, length = 50)
private String category;
@Size(max = 200)
@Column(name = "title", length = 200)
private String title;
@Column(name = "episode")
private Long episode;
@Size(max = 20)
@Column(name = "capacity", length = 20)
private String capacity;
@Column(name = "memo", columnDefinition = "text")
private String memo;
@Size(max = 20)
@NotNull
@Column(name = "status", nullable = false, length = 20)
private String status;
@NotNull
@ColumnDefault("false")
@Column(name = "deleted", nullable = false)
private Boolean deleted = false;
@NotNull
@ColumnDefault("now()")
@Column(name = "created_dttm", nullable = false)
private ZonedDateTime createdDttm = ZonedDateTime.now();
@Column(name = "updated_dttm")
private ZonedDateTime updatedDttm;
@PrePersist
protected void onPersist() {
if (this.createdDttm == null) {
this.createdDttm = ZonedDateTime.now();
}
if (this.deleted == null) {
this.deleted = false;
}
}
@PreUpdate
protected void onUpdate() {
this.updatedDttm = ZonedDateTime.now();
}
}
package com.kamco.cd.training.postgres.entity;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.PrePersist;
import jakarta.persistence.PreUpdate;
import jakarta.persistence.Table;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import java.time.ZonedDateTime;
import lombok.Getter;
import lombok.Setter;
import org.hibernate.annotations.ColumnDefault;
@Getter
@Setter
@Entity
@Table(name = "tb_learn_data")
public class LearnDataEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", nullable = false)
private Long id;
@Size(max = 50)
@NotNull
@Column(name = "category", nullable = false, length = 50)
private String category;
@Size(max = 200)
@Column(name = "title", length = 200)
private String title;
@Column(name = "episode")
private Long episode;
@Size(max = 20)
@Column(name = "capacity", length = 20)
private String capacity;
@Column(name = "memo", columnDefinition = "text")
private String memo;
@Size(max = 20)
@NotNull
@Column(name = "status", nullable = false, length = 20)
private String status;
@NotNull
@ColumnDefault("false")
@Column(name = "deleted", nullable = false)
private Boolean deleted = false;
@NotNull
@ColumnDefault("now()")
@Column(name = "created_dttm", nullable = false)
private ZonedDateTime createdDttm = ZonedDateTime.now();
@Column(name = "updated_dttm")
private ZonedDateTime updatedDttm;
@PrePersist
protected void onPersist() {
if (this.createdDttm == null) {
this.createdDttm = ZonedDateTime.now();
}
if (this.deleted == null) {
this.deleted = false;
}
}
@PreUpdate
protected void onUpdate() {
this.updatedDttm = ZonedDateTime.now();
}
}

View File

@@ -1,105 +1,105 @@
package com.kamco.cd.training.postgres.entity;
import com.kamco.cd.training.dataset.dto.MapSheetDto;
import jakarta.persistence.*;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import java.time.ZonedDateTime;
import lombok.Getter;
import lombok.Setter;
import org.hibernate.annotations.ColumnDefault;
@Getter
@Setter
@Entity
@Table(name = "tb_map_sheet")
public class MapSheetEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", nullable = false)
private Long id;
@NotNull
@Column(name = "object_id", nullable = false)
private Long objectId;
@NotNull
@Column(name = "dataset_id", nullable = false)
private Long datasetId;
@NotNull
@Size(max = 20)
@Column(name = "sheet_num", nullable = false, length = 20)
private String sheetNum;
@Size(max = 255)
@Column(name = "file_name", length = 255)
private String fileName;
@Column(name = "file_size")
private Long fileSize;
@Size(max = 500)
@Column(name = "file_path", length = 500)
private String filePath;
@Size(max = 20)
@Column(name = "status", length = 20)
private String status;
@Column(name = "memo", columnDefinition = "TEXT")
private String memo;
@NotNull
@ColumnDefault("false")
@Column(name = "deleted", nullable = false)
private Boolean deleted = false;
@NotNull
@ColumnDefault("now()")
@Column(name = "created_dttm", nullable = false)
private ZonedDateTime createdDttm;
@Column(name = "updated_dttm")
private ZonedDateTime updatedDttm;
@Column(name = "map_id_cd_no")
private Long mapIdCdNo;
@Size(max = 128)
@Column(name = "map_id_nm", length = 128)
private String mapIdNm;
@Size(max = 128)
@Column(name = "shape_leng", length = 128)
private String shapeLeng;
@Column(name = "shape_area")
private Double shapeArea;
@Column(name = "scale_ratio")
private Long scaleRatio;
@Column(name = "wkt_geom", columnDefinition = "TEXT")
private String wktGeom;
@Column(name = "ref_map_id_cd_no")
private Long refMapIdCdNo;
public MapSheetDto.Basic toDto() {
MapSheetDto.Basic dto = new MapSheetDto.Basic();
dto.setId(this.id);
dto.setDatasetId(this.datasetId);
dto.setSheetNum(this.sheetNum);
dto.setFileName(this.fileName);
dto.setFileSize(this.fileSize);
dto.setFilePath(this.filePath);
dto.setStatus(this.status);
dto.setMemo(this.memo);
dto.setDeleted(this.deleted);
dto.setCreatedDttm(this.createdDttm);
dto.setUpdatedDttm(this.updatedDttm);
return dto;
}
}
package com.kamco.cd.training.postgres.entity;
import com.kamco.cd.training.dataset.dto.MapSheetDto;
import jakarta.persistence.*;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import java.time.ZonedDateTime;
import lombok.Getter;
import lombok.Setter;
import org.hibernate.annotations.ColumnDefault;
@Getter
@Setter
@Entity
@Table(name = "tb_map_sheet")
public class MapSheetEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", nullable = false)
private Long id;
@NotNull
@Column(name = "object_id", nullable = false)
private Long objectId;
@NotNull
@Column(name = "dataset_id", nullable = false)
private Long datasetId;
@NotNull
@Size(max = 20)
@Column(name = "sheet_num", nullable = false, length = 20)
private String sheetNum;
@Size(max = 255)
@Column(name = "file_name", length = 255)
private String fileName;
@Column(name = "file_size")
private Long fileSize;
@Size(max = 500)
@Column(name = "file_path", length = 500)
private String filePath;
@Size(max = 20)
@Column(name = "status", length = 20)
private String status;
@Column(name = "memo", columnDefinition = "TEXT")
private String memo;
@NotNull
@ColumnDefault("false")
@Column(name = "deleted", nullable = false)
private Boolean deleted = false;
@NotNull
@ColumnDefault("now()")
@Column(name = "created_dttm", nullable = false)
private ZonedDateTime createdDttm;
@Column(name = "updated_dttm")
private ZonedDateTime updatedDttm;
@Column(name = "map_id_cd_no")
private Long mapIdCdNo;
@Size(max = 128)
@Column(name = "map_id_nm", length = 128)
private String mapIdNm;
@Size(max = 128)
@Column(name = "shape_leng", length = 128)
private String shapeLeng;
@Column(name = "shape_area")
private Double shapeArea;
@Column(name = "scale_ratio")
private Long scaleRatio;
@Column(name = "wkt_geom", columnDefinition = "TEXT")
private String wktGeom;
@Column(name = "ref_map_id_cd_no")
private Long refMapIdCdNo;
public MapSheetDto.Basic toDto() {
MapSheetDto.Basic dto = new MapSheetDto.Basic();
dto.setId(this.id);
dto.setDatasetId(this.datasetId);
dto.setSheetNum(this.sheetNum);
dto.setFileName(this.fileName);
dto.setFileSize(this.fileSize);
dto.setFilePath(this.filePath);
dto.setStatus(this.status);
dto.setMemo(this.memo);
dto.setDeleted(this.deleted);
dto.setCreatedDttm(this.createdDttm);
dto.setUpdatedDttm(this.updatedDttm);
return dto;
}
}

View File

@@ -1,114 +1,114 @@
package com.kamco.cd.training.postgres.entity;
import com.kamco.cd.training.common.enums.StatusType;
import com.kamco.cd.training.members.dto.MembersDto;
import jakarta.persistence.*;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import java.time.ZonedDateTime;
import java.util.Objects;
import java.util.UUID;
import lombok.Getter;
import lombok.Setter;
import org.hibernate.annotations.ColumnDefault;
@Getter
@Setter
@Entity
@Table(name = "tb_member")
public class MemberEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", nullable = false)
private Long id;
@NotNull
@ColumnDefault("gen_random_uuid()")
@Column(name = "uuid", nullable = false)
private UUID uuid = UUID.randomUUID();
@Size(max = 50)
@NotNull
@Column(name = "user_role", nullable = false, length = 50)
private String userRole;
@Size(max = 50)
@NotNull
@Column(name = "user_id", nullable = false, length = 50)
private String userId;
@Size(max = 50)
@NotNull
@Column(name = "employee_no", nullable = false, length = 50)
private String employeeNo;
@Size(max = 100)
@NotNull
@Column(name = "name", nullable = false, length = 100)
private String name;
@Size(max = 255)
@NotNull
@Column(name = "password", nullable = false)
private String password;
@Size(max = 20)
@Column(name = "status", length = 20)
private String status = StatusType.PENDING.getId();
@NotNull
@ColumnDefault("now()")
@Column(name = "created_dttm", nullable = false)
private ZonedDateTime createdDttm = ZonedDateTime.now();
@ColumnDefault("now()")
@Column(name = "updated_dttm")
private ZonedDateTime updatedDttm = ZonedDateTime.now();
@Column(name = "first_login_dttm")
private ZonedDateTime firstLoginDttm;
@Column(name = "last_login_dttm")
private ZonedDateTime lastLoginDttm;
@Column(name = "login_fail_count")
@ColumnDefault("0")
private Integer loginFailCount = 0;
@Column(name = "rgstr_uid")
private Long rgstrUidl;
@Column(name = "updtr_uid")
private Long updtrUid;
@Column(name = "status_chg_dttm")
private ZonedDateTime statusChgDttm;
@Column(name = "pwd_reset_yn")
private Boolean pwdResetYn;
public void changeStatus(String newStatus) {
// 같은 값 보내도 무시
if (Objects.equals(this.status, newStatus)) {
return;
}
this.status = newStatus;
this.statusChgDttm = ZonedDateTime.now();
}
public MembersDto.Basic toDto() {
return new MembersDto.Basic(
this.id,
this.uuid,
this.userRole,
this.name,
this.employeeNo,
this.status,
this.createdDttm,
this.firstLoginDttm,
this.lastLoginDttm,
this.statusChgDttm,
this.pwdResetYn);
}
}
package com.kamco.cd.training.postgres.entity;
import com.kamco.cd.training.common.enums.StatusType;
import com.kamco.cd.training.members.dto.MembersDto;
import jakarta.persistence.*;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import java.time.ZonedDateTime;
import java.util.Objects;
import java.util.UUID;
import lombok.Getter;
import lombok.Setter;
import org.hibernate.annotations.ColumnDefault;
@Getter
@Setter
@Entity
@Table(name = "tb_member")
public class MemberEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", nullable = false)
private Long id;
@NotNull
@ColumnDefault("gen_random_uuid()")
@Column(name = "uuid", nullable = false)
private UUID uuid = UUID.randomUUID();
@Size(max = 50)
@NotNull
@Column(name = "user_role", nullable = false, length = 50)
private String userRole;
@Size(max = 50)
@NotNull
@Column(name = "user_id", nullable = false, length = 50)
private String userId;
@Size(max = 50)
@NotNull
@Column(name = "employee_no", nullable = false, length = 50)
private String employeeNo;
@Size(max = 100)
@NotNull
@Column(name = "name", nullable = false, length = 100)
private String name;
@Size(max = 255)
@NotNull
@Column(name = "password", nullable = false)
private String password;
@Size(max = 20)
@Column(name = "status", length = 20)
private String status = StatusType.PENDING.getId();
@NotNull
@ColumnDefault("now()")
@Column(name = "created_dttm", nullable = false)
private ZonedDateTime createdDttm = ZonedDateTime.now();
@ColumnDefault("now()")
@Column(name = "updated_dttm")
private ZonedDateTime updatedDttm = ZonedDateTime.now();
@Column(name = "first_login_dttm")
private ZonedDateTime firstLoginDttm;
@Column(name = "last_login_dttm")
private ZonedDateTime lastLoginDttm;
@Column(name = "login_fail_count")
@ColumnDefault("0")
private Integer loginFailCount = 0;
@Column(name = "rgstr_uid")
private Long rgstrUidl;
@Column(name = "updtr_uid")
private Long updtrUid;
@Column(name = "status_chg_dttm")
private ZonedDateTime statusChgDttm;
@Column(name = "pwd_reset_yn")
private Boolean pwdResetYn;
public void changeStatus(String newStatus) {
// 같은 값 보내도 무시
if (Objects.equals(this.status, newStatus)) {
return;
}
this.status = newStatus;
this.statusChgDttm = ZonedDateTime.now();
}
public MembersDto.Basic toDto() {
return new MembersDto.Basic(
this.id,
this.uuid,
this.userRole,
this.name,
this.employeeNo,
this.status,
this.createdDttm,
this.firstLoginDttm,
this.lastLoginDttm,
this.statusChgDttm,
this.pwdResetYn);
}
}

View File

@@ -1,71 +1,71 @@
package com.kamco.cd.training.postgres.entity;
import com.kamco.cd.training.menu.dto.MenuDto;
import com.kamco.cd.training.postgres.CommonDateEntity;
import jakarta.persistence.*;
import jakarta.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.List;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Table(name = "tb_menu")
public class MenuEntity extends CommonDateEntity {
@Id
@Column(name = "menu_uid")
private String menuUid;
@Column(name = "menu_nm")
private String menuNm;
@Column(name = "menu_url")
private String menuUrl;
@Column(name = "description")
private String description;
@Column(name = "menu_order")
private Long menuOrder;
@NotNull
@Column(name = "is_use", nullable = true)
private Boolean isUse = true;
@NotNull
@Column(name = "deleted", nullable = false)
private Boolean deleted = false;
private Long createdUid;
private Long updatedUid;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "parent_menu_uid")
private MenuEntity parent;
@OneToMany(mappedBy = "parent", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private List<MenuEntity> children = new ArrayList<>();
@Column(name = "menu_api_uri")
private String menuApiUri;
public MenuDto.Basic toDto() {
return new MenuDto.Basic(
this.menuUid,
this.menuNm,
this.menuUrl,
this.description,
this.menuOrder,
this.isUse,
this.deleted,
this.createdUid,
this.updatedUid,
this.children.stream().map(MenuEntity::toDto).toList(),
this.getCreatedDate(),
this.getModifiedDate(),
this.menuApiUri);
}
}
package com.kamco.cd.training.postgres.entity;
import com.kamco.cd.training.menu.dto.MenuDto;
import com.kamco.cd.training.postgres.CommonDateEntity;
import jakarta.persistence.*;
import jakarta.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.List;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Table(name = "tb_menu")
public class MenuEntity extends CommonDateEntity {
@Id
@Column(name = "menu_uid")
private String menuUid;
@Column(name = "menu_nm")
private String menuNm;
@Column(name = "menu_url")
private String menuUrl;
@Column(name = "description")
private String description;
@Column(name = "menu_order")
private Long menuOrder;
@NotNull
@Column(name = "is_use", nullable = true)
private Boolean isUse = true;
@NotNull
@Column(name = "deleted", nullable = false)
private Boolean deleted = false;
private Long createdUid;
private Long updatedUid;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "parent_menu_uid")
private MenuEntity parent;
@OneToMany(mappedBy = "parent", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private List<MenuEntity> children = new ArrayList<>();
@Column(name = "menu_api_uri")
private String menuApiUri;
public MenuDto.Basic toDto() {
return new MenuDto.Basic(
this.menuUid,
this.menuNm,
this.menuUrl,
this.description,
this.menuOrder,
this.isUse,
this.deleted,
this.createdUid,
this.updatedUid,
this.children.stream().map(MenuEntity::toDto).toList(),
this.getCreatedDate(),
this.getModifiedDate(),
this.menuApiUri);
}
}

View File

@@ -1,47 +1,47 @@
package com.kamco.cd.training.postgres.entity;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.IdClass;
import jakarta.persistence.Table;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import java.io.Serializable;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
@Setter
@Entity
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "tb_model_dataset_mapp")
@IdClass(ModelDatasetMappEntity.ModelDatasetMappId.class)
public class ModelDatasetMappEntity {
@Id
@NotNull
@Column(name = "model_uid", nullable = false)
private Long modelUid;
@Id
@NotNull
@Column(name = "dataset_uid", nullable = false)
private Long datasetUid;
@Size(max = 20)
@Column(name = "dataset_type", length = 20)
private String datasetType;
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public static class ModelDatasetMappId implements Serializable {
private Long modelUid;
private Long datasetUid;
}
}
package com.kamco.cd.training.postgres.entity;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.IdClass;
import jakarta.persistence.Table;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import java.io.Serializable;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
@Setter
@Entity
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "tb_model_dataset_mapp")
@IdClass(ModelDatasetMappEntity.ModelDatasetMappId.class)
public class ModelDatasetMappEntity {
@Id
@NotNull
@Column(name = "model_uid", nullable = false)
private Long modelUid;
@Id
@NotNull
@Column(name = "dataset_uid", nullable = false)
private Long datasetUid;
@Size(max = 20)
@Column(name = "dataset_type", length = 20)
private String datasetType;
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public static class ModelDatasetMappId implements Serializable {
private Long modelUid;
private Long datasetUid;
}
}

View File

@@ -1,232 +1,232 @@
package com.kamco.cd.training.postgres.entity;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import java.time.ZonedDateTime;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.hibernate.annotations.ColumnDefault;
@Getter
@Setter
@Entity
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "tb_model_hyper_param")
public class ModelHyperParamEntity {
@Id
@NotNull
@Size(max = 50)
@Column(name = "hyper_ver", nullable = false, length = 50)
private String hyperVer;
// ==================== Important Parameters ====================
@Size(max = 20)
@ColumnDefault("'large'")
@Column(name = "backbone", length = 20)
private String backbone = "large";
@Size(max = 20)
@ColumnDefault("'256,256'")
@Column(name = "input_size", length = 20)
private String inputSize = "256,256";
@Size(max = 20)
@ColumnDefault("'256,256'")
@Column(name = "crop_size", length = 20)
private String cropSize = "256,256";
@ColumnDefault("200")
@Column(name = "epoch_cnt")
private Integer epochCnt = 200;
@ColumnDefault("16")
@Column(name = "batch_size")
private Integer batchSize = 16;
// ==================== Model Architecture ====================
@ColumnDefault("0.3")
@Column(name = "drop_path_rate")
private Double dropPathRate = 0.3;
@ColumnDefault("-1")
@Column(name = "frozen_stages")
private Integer frozenStages = -1;
@Size(max = 20)
@ColumnDefault("'abs_diff'")
@Column(name = "neck_policy", length = 20)
private String neckPolicy = "abs_diff";
@Size(max = 255)
@ColumnDefault("'512,256,128,64'")
@Column(name = "decoder_channels", length = 255)
private String decoderChannels = "512,256,128,64";
@Size(max = 500)
@Column(name = "class_weight", length = 500)
private String classWeight;
@Column(name = "num_layers")
private Integer numLayers;
// ==================== Loss & Optimization ====================
@ColumnDefault("0.00006")
@Column(name = "learning_rate")
private Double learningRate = 0.00006;
@ColumnDefault("0.05")
@Column(name = "weight_decay")
private Double weightDecay = 0.05;
@ColumnDefault("0.9")
@Column(name = "layer_decay_rate")
private Double layerDecayRate = 0.9;
@ColumnDefault("true")
@Column(name = "ddp_find_unused_params")
private Boolean ddpFindUnusedParams = true;
@ColumnDefault("255")
@Column(name = "ignore_index")
private Integer ignoreIndex = 255;
// ==================== Data ====================
@ColumnDefault("16")
@Column(name = "train_num_workers")
private Integer trainNumWorkers = 16;
@ColumnDefault("8")
@Column(name = "val_num_workers")
private Integer valNumWorkers = 8;
@ColumnDefault("8")
@Column(name = "test_num_workers")
private Integer testNumWorkers = 8;
@ColumnDefault("true")
@Column(name = "train_shuffle")
private Boolean trainShuffle = true;
@ColumnDefault("true")
@Column(name = "train_persistent")
private Boolean trainPersistent = true;
@ColumnDefault("true")
@Column(name = "val_persistent")
private Boolean valPersistent = true;
// ==================== Evaluation ====================
@Size(max = 255)
@ColumnDefault("'mFscore,mIoU'")
@Column(name = "metrics", length = 255)
private String metrics = "mFscore,mIoU";
@Size(max = 50)
@ColumnDefault("'changed_fscore'")
@Column(name = "save_best", length = 50)
private String saveBest = "changed_fscore";
@Size(max = 20)
@ColumnDefault("'greater'")
@Column(name = "save_best_rule", length = 20)
private String saveBestRule = "greater";
@ColumnDefault("10")
@Column(name = "val_interval")
private Integer valInterval = 10;
@ColumnDefault("400")
@Column(name = "log_interval")
private Integer logInterval = 400;
@ColumnDefault("1")
@Column(name = "vis_interval")
private Integer visInterval = 1;
// ==================== Hardware ====================
@ColumnDefault("4")
@Column(name = "gpu_cnt")
private Integer gpuCnt = 4;
@Size(max = 100)
@ColumnDefault("'0,1,2,3'")
@Column(name = "gpu_ids", length = 100)
private String gpuIds = "0,1,2,3";
@ColumnDefault("1122")
@Column(name = "master_port")
private Integer masterPort = 1122;
// ==================== Augmentation ====================
@ColumnDefault("0.5")
@Column(name = "rot_prob")
private Double rotProb = 0.5;
@ColumnDefault("0.5")
@Column(name = "flip_prob")
private Double flipProb = 0.5;
@Size(max = 20)
@ColumnDefault("'-20,20'")
@Column(name = "rot_degree", length = 20)
private String rotDegree = "-20,20";
@ColumnDefault("0.5")
@Column(name = "exchange_prob")
private Double exchangeProb = 0.5;
@ColumnDefault("10")
@Column(name = "brightness_delta")
private Integer brightnessDelta = 10;
@Size(max = 20)
@ColumnDefault("'0.8,1.2'")
@Column(name = "contrast_range", length = 20)
private String contrastRange = "0.8,1.2";
@Size(max = 20)
@ColumnDefault("'0.8,1.2'")
@Column(name = "saturation_range", length = 20)
private String saturationRange = "0.8,1.2";
@ColumnDefault("10")
@Column(name = "hue_delta")
private Integer hueDelta = 10;
// ==================== Legacy (deprecated) ====================
@Column(name = "cnn_filter_cnt")
private Integer cnnFilterCnt;
@Column(name = "dropout_ratio")
private Double dropoutRatio;
// ==================== Common ====================
@Column(name = "memo", length = Integer.MAX_VALUE)
private String memo;
@Size(max = 255)
@ColumnDefault("'N'")
@Column(name = "del_yn", length = 255)
private String delYn = "N";
@ColumnDefault("now()")
@Column(name = "created_dttm")
private ZonedDateTime createdDttm;
}
package com.kamco.cd.training.postgres.entity;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import java.time.ZonedDateTime;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.hibernate.annotations.ColumnDefault;
@Getter
@Setter
@Entity
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "tb_model_hyper_param")
public class ModelHyperParamEntity {
@Id
@NotNull
@Size(max = 50)
@Column(name = "hyper_ver", nullable = false, length = 50)
private String hyperVer;
// ==================== Important Parameters ====================
@Size(max = 20)
@ColumnDefault("'large'")
@Column(name = "backbone", length = 20)
private String backbone = "large";
@Size(max = 20)
@ColumnDefault("'256,256'")
@Column(name = "input_size", length = 20)
private String inputSize = "256,256";
@Size(max = 20)
@ColumnDefault("'256,256'")
@Column(name = "crop_size", length = 20)
private String cropSize = "256,256";
@ColumnDefault("200")
@Column(name = "epoch_cnt")
private Integer epochCnt = 200;
@ColumnDefault("16")
@Column(name = "batch_size")
private Integer batchSize = 16;
// ==================== Model Architecture ====================
@ColumnDefault("0.3")
@Column(name = "drop_path_rate")
private Double dropPathRate = 0.3;
@ColumnDefault("-1")
@Column(name = "frozen_stages")
private Integer frozenStages = -1;
@Size(max = 20)
@ColumnDefault("'abs_diff'")
@Column(name = "neck_policy", length = 20)
private String neckPolicy = "abs_diff";
@Size(max = 255)
@ColumnDefault("'512,256,128,64'")
@Column(name = "decoder_channels", length = 255)
private String decoderChannels = "512,256,128,64";
@Size(max = 500)
@Column(name = "class_weight", length = 500)
private String classWeight;
@Column(name = "num_layers")
private Integer numLayers;
// ==================== Loss & Optimization ====================
@ColumnDefault("0.00006")
@Column(name = "learning_rate")
private Double learningRate = 0.00006;
@ColumnDefault("0.05")
@Column(name = "weight_decay")
private Double weightDecay = 0.05;
@ColumnDefault("0.9")
@Column(name = "layer_decay_rate")
private Double layerDecayRate = 0.9;
@ColumnDefault("true")
@Column(name = "ddp_find_unused_params")
private Boolean ddpFindUnusedParams = true;
@ColumnDefault("255")
@Column(name = "ignore_index")
private Integer ignoreIndex = 255;
// ==================== Data ====================
@ColumnDefault("16")
@Column(name = "train_num_workers")
private Integer trainNumWorkers = 16;
@ColumnDefault("8")
@Column(name = "val_num_workers")
private Integer valNumWorkers = 8;
@ColumnDefault("8")
@Column(name = "test_num_workers")
private Integer testNumWorkers = 8;
@ColumnDefault("true")
@Column(name = "train_shuffle")
private Boolean trainShuffle = true;
@ColumnDefault("true")
@Column(name = "train_persistent")
private Boolean trainPersistent = true;
@ColumnDefault("true")
@Column(name = "val_persistent")
private Boolean valPersistent = true;
// ==================== Evaluation ====================
@Size(max = 255)
@ColumnDefault("'mFscore,mIoU'")
@Column(name = "metrics", length = 255)
private String metrics = "mFscore,mIoU";
@Size(max = 50)
@ColumnDefault("'changed_fscore'")
@Column(name = "save_best", length = 50)
private String saveBest = "changed_fscore";
@Size(max = 20)
@ColumnDefault("'greater'")
@Column(name = "save_best_rule", length = 20)
private String saveBestRule = "greater";
@ColumnDefault("10")
@Column(name = "val_interval")
private Integer valInterval = 10;
@ColumnDefault("400")
@Column(name = "log_interval")
private Integer logInterval = 400;
@ColumnDefault("1")
@Column(name = "vis_interval")
private Integer visInterval = 1;
// ==================== Hardware ====================
@ColumnDefault("4")
@Column(name = "gpu_cnt")
private Integer gpuCnt = 4;
@Size(max = 100)
@ColumnDefault("'0,1,2,3'")
@Column(name = "gpu_ids", length = 100)
private String gpuIds = "0,1,2,3";
@ColumnDefault("1122")
@Column(name = "master_port")
private Integer masterPort = 1122;
// ==================== Augmentation ====================
@ColumnDefault("0.5")
@Column(name = "rot_prob")
private Double rotProb = 0.5;
@ColumnDefault("0.5")
@Column(name = "flip_prob")
private Double flipProb = 0.5;
@Size(max = 20)
@ColumnDefault("'-20,20'")
@Column(name = "rot_degree", length = 20)
private String rotDegree = "-20,20";
@ColumnDefault("0.5")
@Column(name = "exchange_prob")
private Double exchangeProb = 0.5;
@ColumnDefault("10")
@Column(name = "brightness_delta")
private Integer brightnessDelta = 10;
@Size(max = 20)
@ColumnDefault("'0.8,1.2'")
@Column(name = "contrast_range", length = 20)
private String contrastRange = "0.8,1.2";
@Size(max = 20)
@ColumnDefault("'0.8,1.2'")
@Column(name = "saturation_range", length = 20)
private String saturationRange = "0.8,1.2";
@ColumnDefault("10")
@Column(name = "hue_delta")
private Integer hueDelta = 10;
// ==================== Legacy (deprecated) ====================
@Column(name = "cnn_filter_cnt")
private Integer cnnFilterCnt;
@Column(name = "dropout_ratio")
private Double dropoutRatio;
// ==================== Common ====================
@Column(name = "memo", length = Integer.MAX_VALUE)
private String memo;
@Size(max = 255)
@ColumnDefault("'N'")
@Column(name = "del_yn", length = 255)
private String delYn = "N";
@ColumnDefault("now()")
@Column(name = "created_dttm")
private ZonedDateTime createdDttm;
}

View File

@@ -1,94 +1,94 @@
package com.kamco.cd.training.postgres.entity;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.PrePersist;
import jakarta.persistence.Table;
import jakarta.validation.constraints.Size;
import java.time.Instant;
import java.time.ZonedDateTime;
import java.util.UUID;
import lombok.Getter;
import lombok.Setter;
import org.hibernate.annotations.ColumnDefault;
@Getter
@Setter
@Entity
@Table(name = "tb_model_mng")
public class ModelMngEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "model_uid", nullable = false)
private Long id;
@Column(name = "uuid", columnDefinition = "uuid", nullable = false, updatable = false)
private UUID uuid;
@Size(max = 100)
@ColumnDefault("'NULL::character varying'")
@Column(name = "model_nm", length = 100)
private String modelNm;
@Size(max = 64)
@ColumnDefault("'NULL::character varying'")
@Column(name = "model_cate", length = 64)
private String modelCate;
@Size(max = 255)
@ColumnDefault("'NULL::character varying'")
@Column(name = "model_path")
private String modelPath;
@Column(name = "created_dttm")
private Instant createdDttm;
@Column(name = "created_uid")
private Long createdUid;
@Column(name = "updated_dttm")
private Instant updatedDttm;
@Column(name = "updated_uid")
private Long updatedUid;
@Column(name = "start_dttm")
private ZonedDateTime startDttm;
@Column(name = "training_end_dttm")
private ZonedDateTime trainingEndDttm;
@Column(name = "test_end_dttm")
private ZonedDateTime testEndDttm;
@Column(name = "duration_dttm")
private ZonedDateTime durationDttm;
@Size(max = 50)
@Column(name = "process_stage", length = 50)
private String processStage;
@Size(max = 50)
@Column(name = "status", length = 50)
private String status;
@ColumnDefault("false")
@Column(name = "deleted")
private Boolean deleted;
@PrePersist
public void prePersist() {
if (this.uuid == null) {
this.uuid = UUID.randomUUID();
}
}
/** UUID 필드가 제대로 설정되었는지 확인 (디버그용) */
public String getUuidString() {
return this.uuid != null ? this.uuid.toString() : null;
}
}
package com.kamco.cd.training.postgres.entity;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.PrePersist;
import jakarta.persistence.Table;
import jakarta.validation.constraints.Size;
import java.time.Instant;
import java.time.ZonedDateTime;
import java.util.UUID;
import lombok.Getter;
import lombok.Setter;
import org.hibernate.annotations.ColumnDefault;
@Getter
@Setter
@Entity
@Table(name = "tb_model_mng")
public class ModelMngEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "model_uid", nullable = false)
private Long id;
@Column(name = "uuid", columnDefinition = "uuid", nullable = false, updatable = false)
private UUID uuid;
@Size(max = 100)
@ColumnDefault("'NULL::character varying'")
@Column(name = "model_nm", length = 100)
private String modelNm;
@Size(max = 64)
@ColumnDefault("'NULL::character varying'")
@Column(name = "model_cate", length = 64)
private String modelCate;
@Size(max = 255)
@ColumnDefault("'NULL::character varying'")
@Column(name = "model_path")
private String modelPath;
@Column(name = "created_dttm")
private Instant createdDttm;
@Column(name = "created_uid")
private Long createdUid;
@Column(name = "updated_dttm")
private Instant updatedDttm;
@Column(name = "updated_uid")
private Long updatedUid;
@Column(name = "start_dttm")
private ZonedDateTime startDttm;
@Column(name = "training_end_dttm")
private ZonedDateTime trainingEndDttm;
@Column(name = "test_end_dttm")
private ZonedDateTime testEndDttm;
@Column(name = "duration_dttm")
private ZonedDateTime durationDttm;
@Size(max = 50)
@Column(name = "process_stage", length = 50)
private String processStage;
@Size(max = 50)
@Column(name = "status", length = 50)
private String status;
@ColumnDefault("false")
@Column(name = "deleted")
private Boolean deleted;
@PrePersist
public void prePersist() {
if (this.uuid == null) {
this.uuid = UUID.randomUUID();
}
}
/** UUID 필드가 제대로 설정되었는지 확인 (디버그용) */
public String getUuidString() {
return this.uuid != null ? this.uuid.toString() : null;
}
}

View File

@@ -1,170 +1,170 @@
package com.kamco.cd.training.postgres.entity;
import com.kamco.cd.training.model.dto.ModelMngDto;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.PrePersist;
import jakarta.persistence.Table;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import java.time.Instant;
import java.time.ZonedDateTime;
import java.util.UUID;
import lombok.Getter;
import lombok.Setter;
import org.hibernate.annotations.ColumnDefault;
@Getter
@Setter
@Entity
@Table(name = "tb_model_train_master")
public class ModelTrainMasterEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "model_uid", nullable = false)
private Long id;
@Column(name = "uuid", columnDefinition = "uuid", nullable = false, updatable = false)
private UUID uuid;
@Size(max = 50)
@NotNull
@Column(name = "model_ver", nullable = false, length = 50)
private String modelVer;
@Size(max = 50)
@Column(name = "hyper_ver", length = 50)
private String hyperVer;
@Size(max = 50)
@Column(name = "epoch_ver", length = 50)
private String epochVer;
@Size(max = 50)
@Column(name = "process_step", length = 50)
private String processStep;
@Size(max = 20)
@Column(name = "status_cd", length = 20)
private String statusCd;
@Column(name = "train_start_dttm")
private ZonedDateTime trainStartDttm;
@Column(name = "epoch_cnt")
private Integer epochCnt;
@Size(max = 50)
@Column(name = "dataset_ratio", length = 50)
private String datasetRatio;
@Column(name = "best_epoch")
private Integer bestEpoch;
@Column(name = "step1_end_dttm")
private ZonedDateTime step1EndDttm;
@Size(max = 50)
@Column(name = "step1_duration", length = 50)
private String step1Duration;
@Column(name = "step2_end_dttm")
private ZonedDateTime step2EndDttm;
@Size(max = 50)
@Column(name = "step2_duration", length = 50)
private String step2Duration;
@ColumnDefault("false")
@Column(name = "del_yn")
private Boolean delYn = false;
@Column(name = "created_uid")
private Long createdUid;
@Column(name = "updated_uid")
private Long updatedUid;
@ColumnDefault("now()")
@Column(name = "created_dttm")
private ZonedDateTime createdDttm;
@Column(name = "updated_dttm")
private ZonedDateTime updatedDttm;
@ColumnDefault("0")
@Column(name = "progress_rate")
private Integer progressRate;
@Column(name = "stop_dttm")
private Instant stopDttm;
@Column(name = "confirmed_best_epoch")
private Integer confirmedBestEpoch;
@Size(max = 255)
@Column(name = "model_path")
private String modelPath;
@Column(name = "error_msg", length = Integer.MAX_VALUE)
private String errorMsg;
// ==================== Resume Training (학습 재시작) ====================
@Column(name = "last_checkpoint_epoch")
private Integer lastCheckpointEpoch;
@Size(max = 500)
@Column(name = "checkpoint_path", length = 500)
private String checkpointPath;
@ColumnDefault("false")
@Column(name = "can_resume")
private Boolean canResume = false;
@Column(name = "step2_start_dttm")
private Instant step2StartDttm;
@Size(max = 1000)
@Column(name = "train_log_path", length = 1000)
private String trainLogPath;
@Column(name = "memo", length = Integer.MAX_VALUE)
private String memo;
@Column(name = "base_model_uid")
private Integer baseModelUid;
@Size(max = 1000)
@Column(name = "pretrained_model_path", length = 1000)
private String pretrainedModelPath;
@PrePersist
public void prePersist() {
if (this.uuid == null) {
this.uuid = UUID.randomUUID();
}
}
public ModelMngDto.Basic toDto() {
ModelMngDto.Basic dto = new ModelMngDto.Basic();
dto.setId(this.id);
dto.setModelNm(this.modelVer);
dto.setStartDttm(this.trainStartDttm);
dto.setTrainingEndDttm(this.step1EndDttm);
dto.setTestEndDttm(this.step2EndDttm);
dto.setDurationDttm(this.step2Duration);
dto.setProcessStage(this.processStep);
dto.setStatusCd(this.statusCd);
return dto;
}
/** UUID 필드가 제대로 설정되었는지 확인 (디버그용) */
public String getUuidString() {
return this.uuid != null ? this.uuid.toString() : null;
}
}
package com.kamco.cd.training.postgres.entity;
import com.kamco.cd.training.model.dto.ModelMngDto;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.PrePersist;
import jakarta.persistence.Table;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import java.time.Instant;
import java.time.ZonedDateTime;
import java.util.UUID;
import lombok.Getter;
import lombok.Setter;
import org.hibernate.annotations.ColumnDefault;
@Getter
@Setter
@Entity
@Table(name = "tb_model_train_master")
public class ModelTrainMasterEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "model_uid", nullable = false)
private Long id;
@Column(name = "uuid", columnDefinition = "uuid", nullable = false, updatable = false)
private UUID uuid;
@Size(max = 50)
@NotNull
@Column(name = "model_ver", nullable = false, length = 50)
private String modelVer;
@Size(max = 50)
@Column(name = "hyper_ver", length = 50)
private String hyperVer;
@Size(max = 50)
@Column(name = "epoch_ver", length = 50)
private String epochVer;
@Size(max = 50)
@Column(name = "process_step", length = 50)
private String processStep;
@Size(max = 20)
@Column(name = "status_cd", length = 20)
private String statusCd;
@Column(name = "train_start_dttm")
private ZonedDateTime trainStartDttm;
@Column(name = "epoch_cnt")
private Integer epochCnt;
@Size(max = 50)
@Column(name = "dataset_ratio", length = 50)
private String datasetRatio;
@Column(name = "best_epoch")
private Integer bestEpoch;
@Column(name = "step1_end_dttm")
private ZonedDateTime step1EndDttm;
@Size(max = 50)
@Column(name = "step1_duration", length = 50)
private String step1Duration;
@Column(name = "step2_end_dttm")
private ZonedDateTime step2EndDttm;
@Size(max = 50)
@Column(name = "step2_duration", length = 50)
private String step2Duration;
@ColumnDefault("false")
@Column(name = "del_yn")
private Boolean delYn = false;
@Column(name = "created_uid")
private Long createdUid;
@Column(name = "updated_uid")
private Long updatedUid;
@ColumnDefault("now()")
@Column(name = "created_dttm")
private ZonedDateTime createdDttm;
@Column(name = "updated_dttm")
private ZonedDateTime updatedDttm;
@ColumnDefault("0")
@Column(name = "progress_rate")
private Integer progressRate;
@Column(name = "stop_dttm")
private Instant stopDttm;
@Column(name = "confirmed_best_epoch")
private Integer confirmedBestEpoch;
@Size(max = 255)
@Column(name = "model_path")
private String modelPath;
@Column(name = "error_msg", length = Integer.MAX_VALUE)
private String errorMsg;
// ==================== Resume Training (학습 재시작) ====================
@Column(name = "last_checkpoint_epoch")
private Integer lastCheckpointEpoch;
@Size(max = 500)
@Column(name = "checkpoint_path", length = 500)
private String checkpointPath;
@ColumnDefault("false")
@Column(name = "can_resume")
private Boolean canResume = false;
@Column(name = "step2_start_dttm")
private Instant step2StartDttm;
@Size(max = 1000)
@Column(name = "train_log_path", length = 1000)
private String trainLogPath;
@Column(name = "memo", length = Integer.MAX_VALUE)
private String memo;
@Column(name = "base_model_uid")
private Integer baseModelUid;
@Size(max = 1000)
@Column(name = "pretrained_model_path", length = 1000)
private String pretrainedModelPath;
@PrePersist
public void prePersist() {
if (this.uuid == null) {
this.uuid = UUID.randomUUID();
}
}
public ModelMngDto.Basic toDto() {
ModelMngDto.Basic dto = new ModelMngDto.Basic();
dto.setId(this.id);
dto.setModelNm(this.modelVer);
dto.setStartDttm(this.trainStartDttm);
dto.setTrainingEndDttm(this.step1EndDttm);
dto.setTestEndDttm(this.step2EndDttm);
dto.setDurationDttm(this.step2Duration);
dto.setProcessStage(this.processStep);
dto.setStatusCd(this.statusCd);
return dto;
}
/** UUID 필드가 제대로 설정되었는지 확인 (디버그용) */
public String getUuidString() {
return this.uuid != null ? this.uuid.toString() : null;
}
}

View File

@@ -1,55 +1,55 @@
package com.kamco.cd.training.postgres.entity;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import java.time.ZonedDateTime;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Entity
@Table(name = "system_metrics")
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class SystemMetricsEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(nullable = false)
private ZonedDateTime timestamp;
@Column(name = "server_name", nullable = false)
private String serverName;
@Column(name = "cpu_user")
private Float cpuUser;
@Column(name = "cpu_system")
private Float cpuSystem;
@Column(name = "cpu_iowait")
private Float cpuIowait;
@Column(name = "cpu_idle")
private Float cpuIdle;
@Column(name = "kbmemfree")
private Long kbmemfree;
@Column(name = "kbmemused")
private Long kbmemused;
@Column(name = "memused")
private Float memused;
}
package com.kamco.cd.training.postgres.entity;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import java.time.ZonedDateTime;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Entity
@Table(name = "system_metrics")
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class SystemMetricsEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(nullable = false)
private ZonedDateTime timestamp;
@Column(name = "server_name", nullable = false)
private String serverName;
@Column(name = "cpu_user")
private Float cpuUser;
@Column(name = "cpu_system")
private Float cpuSystem;
@Column(name = "cpu_iowait")
private Float cpuIowait;
@Column(name = "cpu_idle")
private Float cpuIdle;
@Column(name = "kbmemfree")
private Long kbmemfree;
@Column(name = "kbmemused")
private Long kbmemused;
@Column(name = "memused")
private Float memused;
}

View File

@@ -1,102 +1,97 @@
package com.kamco.cd.training.postgres.entity;
import com.kamco.cd.training.upload.dto.UploadDto;
import jakarta.persistence.*;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import java.time.ZonedDateTime;
import java.util.UUID;
import lombok.Getter;
import lombok.Setter;
import org.hibernate.annotations.ColumnDefault;
@Getter
@Setter
@Entity
@Table(name = "tb_upload_session")
public class UploadSessionEntity {
@Id
@Column(name = "upload_id", nullable = false, length = 100)
private String uploadId;
@Size(max = 255)
@NotNull
@Column(name = "file_name", nullable = false, length = 255)
private String fileName;
@NotNull
@Column(name = "file_size", nullable = false)
private Long fileSize;
@Column(name = "dataset_id")
private Long datasetId;
@Column(name = "total_chunks")
private Integer totalChunks;
@Column(name = "uploaded_chunks")
private Integer uploadedChunks = 0;
@Size(max = 20)
@NotNull
@Column(name = "status", nullable = false, length = 20)
private String status; // INIT, UPLOADING, PROCESSING, COMPLETED, FAILED
@Size(max = 500)
@Column(name = "temp_path", length = 500)
private String tempPath;
@Size(max = 500)
@Column(name = "final_path", length = 500)
private String finalPath;
@Column(name = "error_message", columnDefinition = "text")
private String errorMessage;
@NotNull
@ColumnDefault("now()")
@Column(name = "created_dttm", nullable = false)
private ZonedDateTime createdDttm = ZonedDateTime.now();
@NotNull
@ColumnDefault("now()")
@Column(name = "updated_dttm", nullable = false)
private ZonedDateTime updatedDttm = ZonedDateTime.now();
@Column(name = "completed_dttm")
private ZonedDateTime completedDttm;
@Size(max = 50)
@Column(name = "upload_divi", length = 50)
private String uploadDivi;
@Size(max = 300)
@Column(name = "file_hash", length = 300)
private String fileHash;
@Column(name = "chunk_total_index")
private Integer chunkTotalIndex;
@Column(name = "chunk_index")
private Integer chunkIndex = 0;
@NotNull
@ColumnDefault("uuid_generate_v4()")
@Column(name = "uuid", nullable = false)
private UUID uuid;
@PrePersist
protected void onPersist() {
if (this.createdDttm == null) {
this.createdDttm = ZonedDateTime.now();
}
if (this.chunkIndex == null) {
this.chunkIndex = 0;
}
}
}
package com.kamco.cd.training.postgres.entity;
import jakarta.persistence.*;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import java.time.ZonedDateTime;
import java.util.UUID;
import lombok.Getter;
import lombok.Setter;
import org.hibernate.annotations.ColumnDefault;
@Getter
@Setter
@Entity
@Table(name = "tb_upload_session")
public class UploadSessionEntity {
@Id
@Column(name = "upload_id", nullable = false, length = 100)
private String uploadId;
@Size(max = 255)
@NotNull
@Column(name = "file_name", nullable = false, length = 255)
private String fileName;
@NotNull
@Column(name = "file_size", nullable = false)
private Long fileSize;
@Column(name = "dataset_id")
private Long datasetId;
@Column(name = "total_chunks")
private Integer totalChunks;
@Column(name = "uploaded_chunks")
private Integer uploadedChunks = 0;
@Size(max = 20)
@NotNull
@Column(name = "status", nullable = false, length = 20)
private String status; // INIT, UPLOADING, PROCESSING, COMPLETED, FAILED
@Size(max = 500)
@Column(name = "temp_path", length = 500)
private String tempPath;
@Size(max = 500)
@Column(name = "final_path", length = 500)
private String finalPath;
@Column(name = "error_message", columnDefinition = "text")
private String errorMessage;
@NotNull
@ColumnDefault("now()")
@Column(name = "created_dttm", nullable = false)
private ZonedDateTime createdDttm = ZonedDateTime.now();
@NotNull
@ColumnDefault("now()")
@Column(name = "updated_dttm", nullable = false)
private ZonedDateTime updatedDttm = ZonedDateTime.now();
@Column(name = "completed_dttm")
private ZonedDateTime completedDttm;
@Size(max = 50)
@Column(name = "upload_divi", length = 50)
private String uploadDivi;
@Size(max = 300)
@Column(name = "file_hash", length = 300)
private String fileHash;
@Column(name = "chunk_total_index")
private Integer chunkTotalIndex;
@Column(name = "chunk_index")
private Integer chunkIndex = 0;
@NotNull
@ColumnDefault("uuid_generate_v4()")
@Column(name = "uuid", nullable = false)
private UUID uuid;
@PrePersist
protected void onPersist() {
if (this.createdDttm == null) {
this.createdDttm = ZonedDateTime.now();
}
if (this.chunkIndex == null) {
this.chunkIndex = 0;
}
}
}

View File

@@ -1,19 +1,19 @@
package com.kamco.cd.training.postgres.repository;
import com.kamco.cd.training.postgres.entity.SystemMetricsEntity;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
@Repository
public interface SystemMetricsRepository extends JpaRepository<SystemMetricsEntity, Integer> {
/**
* 가장 최근의 시스템 메트릭 조회
*
* @return 최근 시스템 메트릭
*/
@Query("SELECT s FROM SystemMetricsEntity s ORDER BY s.timestamp DESC LIMIT 1")
Optional<SystemMetricsEntity> findLatestMetrics();
}
package com.kamco.cd.training.postgres.repository;
import com.kamco.cd.training.postgres.entity.SystemMetricsEntity;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
@Repository
public interface SystemMetricsRepository extends JpaRepository<SystemMetricsEntity, Integer> {
/**
* 가장 최근의 시스템 메트릭 조회
*
* @return 최근 시스템 메트릭
*/
@Query("SELECT s FROM SystemMetricsEntity s ORDER BY s.timestamp DESC LIMIT 1")
Optional<SystemMetricsEntity> findLatestMetrics();
}

View File

@@ -1,7 +1,7 @@
package com.kamco.cd.training.postgres.repository.code;
import com.kamco.cd.training.postgres.entity.CommonCodeEntity;
import org.springframework.data.jpa.repository.JpaRepository;
public interface CommonCodeRepository
extends JpaRepository<CommonCodeEntity, Long>, CommonCodeRepositoryCustom {}
package com.kamco.cd.training.postgres.repository.code;
import com.kamco.cd.training.postgres.entity.CommonCodeEntity;
import org.springframework.data.jpa.repository.JpaRepository;
public interface CommonCodeRepository
extends JpaRepository<CommonCodeEntity, Long>, CommonCodeRepositoryCustom {}

View File

@@ -1,18 +1,18 @@
package com.kamco.cd.training.postgres.repository.code;
import com.kamco.cd.training.postgres.entity.CommonCodeEntity;
import jakarta.validation.constraints.NotEmpty;
import java.util.List;
import java.util.Optional;
public interface CommonCodeRepositoryCustom {
Optional<CommonCodeEntity> findByCodeId(Long id);
Optional<CommonCodeEntity> findByCode(String code);
List<CommonCodeEntity> findByAll();
Optional<String> getCode(String parentCodeCd, String childCodeCd);
Long findByParentIdCodeExists(Long parentId, @NotEmpty String code);
}
package com.kamco.cd.training.postgres.repository.code;
import com.kamco.cd.training.postgres.entity.CommonCodeEntity;
import jakarta.validation.constraints.NotEmpty;
import java.util.List;
import java.util.Optional;
public interface CommonCodeRepositoryCustom {
Optional<CommonCodeEntity> findByCodeId(Long id);
Optional<CommonCodeEntity> findByCode(String code);
List<CommonCodeEntity> findByAll();
Optional<String> getCode(String parentCodeCd, String childCodeCd);
Long findByParentIdCodeExists(Long parentId, @NotEmpty String code);
}

View File

@@ -1,89 +1,89 @@
package com.kamco.cd.training.postgres.repository.code;
import static com.kamco.cd.training.postgres.entity.QCommonCodeEntity.commonCodeEntity;
import com.kamco.cd.training.postgres.entity.CommonCodeEntity;
import com.kamco.cd.training.postgres.entity.QCommonCodeEntity;
import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.jpa.impl.JPAQueryFactory;
import java.util.List;
import java.util.Optional;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;
@Repository
@RequiredArgsConstructor
public class CommonCodeRepositoryImpl implements CommonCodeRepositoryCustom {
private final JPAQueryFactory queryFactory;
@Override
public Optional<CommonCodeEntity> findByCodeId(Long id) {
return Optional.ofNullable(
queryFactory.selectFrom(commonCodeEntity).where(commonCodeEntity.id.eq(id)).fetchOne());
}
@Override
public Optional<CommonCodeEntity> findByCode(String code) {
QCommonCodeEntity child = new QCommonCodeEntity("child");
return Optional.ofNullable(
queryFactory
.selectFrom(commonCodeEntity)
.leftJoin(commonCodeEntity.children, child)
.on(child.deleted.isFalse().or(child.deleted.isNull()))
.where(
commonCodeEntity.parent.isNull(),
commonCodeEntity.code.eq(code),
commonCodeEntity.used.isTrue(),
commonCodeEntity.deleted.isFalse().or(commonCodeEntity.deleted.isNull()))
.orderBy(child.order.asc())
.fetchOne());
}
@Override
public List<CommonCodeEntity> findByAll() {
QCommonCodeEntity child = new QCommonCodeEntity("child");
return queryFactory
.selectFrom(commonCodeEntity)
.leftJoin(commonCodeEntity.children, child)
.on(child.deleted.isFalse().or(child.deleted.isNull()))
.where(
commonCodeEntity.parent.isNull(),
commonCodeEntity.deleted.isFalse().or(commonCodeEntity.deleted.isNull()))
.orderBy(commonCodeEntity.order.asc(), child.order.asc())
.fetch();
}
@Override
public Optional<String> getCode(String parentCodeCd, String childCodeCd) {
QCommonCodeEntity parent = QCommonCodeEntity.commonCodeEntity;
QCommonCodeEntity child = new QCommonCodeEntity("child");
String result =
queryFactory
.select(child.name)
.from(child)
.join(child.parent, parent)
.where(
parent.code.eq(parentCodeCd).and(child.code.eq(childCodeCd)),
child.deleted.isFalse().or(child.deleted.isNull()))
.fetchFirst(); // 단일 결과만
return Optional.ofNullable(result);
}
@Override
public Long findByParentIdCodeExists(Long parentId, String code) {
return queryFactory
.select(commonCodeEntity.code.count())
.from(commonCodeEntity)
.where(conditionParentId(parentId), commonCodeEntity.code.eq(code))
.fetchOne();
}
private BooleanExpression conditionParentId(Long parentId) {
return parentId == null
? commonCodeEntity.parent.id.isNull()
: commonCodeEntity.parent.id.eq(parentId);
}
}
package com.kamco.cd.training.postgres.repository.code;
import static com.kamco.cd.training.postgres.entity.QCommonCodeEntity.commonCodeEntity;
import com.kamco.cd.training.postgres.entity.CommonCodeEntity;
import com.kamco.cd.training.postgres.entity.QCommonCodeEntity;
import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.jpa.impl.JPAQueryFactory;
import java.util.List;
import java.util.Optional;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;
@Repository
@RequiredArgsConstructor
public class CommonCodeRepositoryImpl implements CommonCodeRepositoryCustom {
private final JPAQueryFactory queryFactory;
@Override
public Optional<CommonCodeEntity> findByCodeId(Long id) {
return Optional.ofNullable(
queryFactory.selectFrom(commonCodeEntity).where(commonCodeEntity.id.eq(id)).fetchOne());
}
@Override
public Optional<CommonCodeEntity> findByCode(String code) {
QCommonCodeEntity child = new QCommonCodeEntity("child");
return Optional.ofNullable(
queryFactory
.selectFrom(commonCodeEntity)
.leftJoin(commonCodeEntity.children, child)
.on(child.deleted.isFalse().or(child.deleted.isNull()))
.where(
commonCodeEntity.parent.isNull(),
commonCodeEntity.code.eq(code),
commonCodeEntity.used.isTrue(),
commonCodeEntity.deleted.isFalse().or(commonCodeEntity.deleted.isNull()))
.orderBy(child.order.asc())
.fetchOne());
}
@Override
public List<CommonCodeEntity> findByAll() {
QCommonCodeEntity child = new QCommonCodeEntity("child");
return queryFactory
.selectFrom(commonCodeEntity)
.leftJoin(commonCodeEntity.children, child)
.on(child.deleted.isFalse().or(child.deleted.isNull()))
.where(
commonCodeEntity.parent.isNull(),
commonCodeEntity.deleted.isFalse().or(commonCodeEntity.deleted.isNull()))
.orderBy(commonCodeEntity.order.asc(), child.order.asc())
.fetch();
}
@Override
public Optional<String> getCode(String parentCodeCd, String childCodeCd) {
QCommonCodeEntity parent = QCommonCodeEntity.commonCodeEntity;
QCommonCodeEntity child = new QCommonCodeEntity("child");
String result =
queryFactory
.select(child.name)
.from(child)
.join(child.parent, parent)
.where(
parent.code.eq(parentCodeCd).and(child.code.eq(childCodeCd)),
child.deleted.isFalse().or(child.deleted.isNull()))
.fetchFirst(); // 단일 결과만
return Optional.ofNullable(result);
}
@Override
public Long findByParentIdCodeExists(Long parentId, String code) {
return queryFactory
.select(commonCodeEntity.code.count())
.from(commonCodeEntity)
.where(conditionParentId(parentId), commonCodeEntity.code.eq(code))
.fetchOne();
}
private BooleanExpression conditionParentId(Long parentId) {
return parentId == null
? commonCodeEntity.parent.id.isNull()
: commonCodeEntity.parent.id.eq(parentId);
}
}

View File

@@ -1,11 +1,11 @@
package com.kamco.cd.training.postgres.repository.dataset;
import com.kamco.cd.training.postgres.entity.DatasetEntity;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
public interface DatasetRepository
extends JpaRepository<DatasetEntity, Long>, DatasetRepositoryCustom {
List<DatasetEntity> findByDeletedOrderByCreatedDttmDesc(Boolean deleted);
}
package com.kamco.cd.training.postgres.repository.dataset;
import com.kamco.cd.training.postgres.entity.DatasetEntity;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
public interface DatasetRepository
extends JpaRepository<DatasetEntity, Long>, DatasetRepositoryCustom {
List<DatasetEntity> findByDeletedOrderByCreatedDttmDesc(Boolean deleted);
}

View File

@@ -1,13 +1,13 @@
package com.kamco.cd.training.postgres.repository.dataset;
import com.kamco.cd.training.dataset.dto.DatasetDto;
import com.kamco.cd.training.postgres.entity.DatasetEntity;
import java.util.Optional;
import java.util.UUID;
import org.springframework.data.domain.Page;
public interface DatasetRepositoryCustom {
Page<DatasetEntity> findDatasetList(DatasetDto.SearchReq searchReq);
Optional<DatasetEntity> findByUuid(UUID id);
}
package com.kamco.cd.training.postgres.repository.dataset;
import com.kamco.cd.training.dataset.dto.DatasetDto;
import com.kamco.cd.training.postgres.entity.DatasetEntity;
import java.util.Optional;
import java.util.UUID;
import org.springframework.data.domain.Page;
public interface DatasetRepositoryCustom {
Page<DatasetEntity> findDatasetList(DatasetDto.SearchReq searchReq);
Optional<DatasetEntity> findByUuid(UUID id);
}

View File

@@ -1,75 +1,75 @@
package com.kamco.cd.training.postgres.repository.dataset;
import com.kamco.cd.training.dataset.dto.DatasetDto;
import com.kamco.cd.training.postgres.entity.DatasetEntity;
import com.kamco.cd.training.postgres.entity.QDatasetEntity;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.jpa.impl.JPAQueryFactory;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Repository;
@Repository
@RequiredArgsConstructor
public class DatasetRepositoryImpl implements DatasetRepositoryCustom {
private final JPAQueryFactory queryFactory;
private final QDatasetEntity dataset = QDatasetEntity.datasetEntity;
/**
* 데이터셋 목록 조회
*
* @param searchReq 검색 조건
* @return 페이징 처리된 데이터셋 Entity 목록
*/
@Override
public Page<DatasetEntity> findDatasetList(DatasetDto.SearchReq searchReq) {
Pageable pageable = searchReq.toPageable();
BooleanBuilder builder = new BooleanBuilder();
// 제목
if (StringUtils.isNotBlank(searchReq.getTitle())) {
String contains = "%" + searchReq.getTitle() + "%";
builder.and(dataset.title.likeIgnoreCase(contains));
}
// 구분
if (StringUtils.isNotBlank(searchReq.getGroupTitle())) {
builder.and(dataset.groupTitle.eq(searchReq.getGroupTitle()));
}
// Entity 직접 조회 (Projections 사용 지양)
List<DatasetEntity> content =
queryFactory
.selectFrom(dataset)
.where(builder.and(dataset.deleted.isFalse()))
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.orderBy(dataset.createdDttm.desc())
.fetch();
// Count 쿼리 별도 실행 (null safe handling)
long total =
Optional.ofNullable(
queryFactory.select(dataset.count()).from(dataset).where(builder).fetchOne())
.orElse(0L);
return new PageImpl<>(content, pageable, total);
}
@Override
public Optional<DatasetEntity> findByUuid(UUID id) {
return Optional.ofNullable(
queryFactory
.select(dataset)
.from(dataset)
.where(dataset.uuid.eq(id), dataset.deleted.isFalse())
.fetchOne());
}
}
package com.kamco.cd.training.postgres.repository.dataset;
import com.kamco.cd.training.dataset.dto.DatasetDto;
import com.kamco.cd.training.postgres.entity.DatasetEntity;
import com.kamco.cd.training.postgres.entity.QDatasetEntity;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.jpa.impl.JPAQueryFactory;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Repository;
@Repository
@RequiredArgsConstructor
public class DatasetRepositoryImpl implements DatasetRepositoryCustom {
private final JPAQueryFactory queryFactory;
private final QDatasetEntity dataset = QDatasetEntity.datasetEntity;
/**
* 데이터셋 목록 조회
*
* @param searchReq 검색 조건
* @return 페이징 처리된 데이터셋 Entity 목록
*/
@Override
public Page<DatasetEntity> findDatasetList(DatasetDto.SearchReq searchReq) {
Pageable pageable = searchReq.toPageable();
BooleanBuilder builder = new BooleanBuilder();
// 제목
if (StringUtils.isNotBlank(searchReq.getTitle())) {
String contains = "%" + searchReq.getTitle() + "%";
builder.and(dataset.title.likeIgnoreCase(contains));
}
// 구분
if (StringUtils.isNotBlank(searchReq.getGroupTitle())) {
builder.and(dataset.groupTitle.eq(searchReq.getGroupTitle()));
}
// Entity 직접 조회 (Projections 사용 지양)
List<DatasetEntity> content =
queryFactory
.selectFrom(dataset)
.where(builder.and(dataset.deleted.isFalse()))
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.orderBy(dataset.createdDttm.desc())
.fetch();
// Count 쿼리 별도 실행 (null safe handling)
long total =
Optional.ofNullable(
queryFactory.select(dataset.count()).from(dataset).where(builder).fetchOne())
.orElse(0L);
return new PageImpl<>(content, pageable, total);
}
@Override
public Optional<DatasetEntity> findByUuid(UUID id) {
return Optional.ofNullable(
queryFactory
.select(dataset)
.from(dataset)
.where(dataset.uuid.eq(id), dataset.deleted.isFalse())
.fetchOne());
}
}

View File

@@ -1,13 +1,13 @@
package com.kamco.cd.training.postgres.repository.dataset;
import com.kamco.cd.training.postgres.entity.MapSheetEntity;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
public interface MapSheetRepository
extends JpaRepository<MapSheetEntity, Long>, MapSheetRepositoryCustom {
List<MapSheetEntity> findByDatasetIdAndDeletedFalse(Long datasetId);
long countByDatasetIdAndDeletedFalse(Long datasetId);
}
package com.kamco.cd.training.postgres.repository.dataset;
import com.kamco.cd.training.postgres.entity.MapSheetEntity;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
public interface MapSheetRepository
extends JpaRepository<MapSheetEntity, Long>, MapSheetRepositoryCustom {
List<MapSheetEntity> findByDatasetIdAndDeletedFalse(Long datasetId);
long countByDatasetIdAndDeletedFalse(Long datasetId);
}

View File

@@ -1,9 +1,9 @@
package com.kamco.cd.training.postgres.repository.dataset;
import com.kamco.cd.training.dataset.dto.MapSheetDto;
import com.kamco.cd.training.postgres.entity.MapSheetEntity;
import org.springframework.data.domain.Page;
public interface MapSheetRepositoryCustom {
Page<MapSheetEntity> findMapSheetList(MapSheetDto.SearchReq searchReq);
}
package com.kamco.cd.training.postgres.repository.dataset;
import com.kamco.cd.training.dataset.dto.MapSheetDto;
import com.kamco.cd.training.postgres.entity.MapSheetEntity;
import org.springframework.data.domain.Page;
public interface MapSheetRepositoryCustom {
Page<MapSheetEntity> findMapSheetList(MapSheetDto.SearchReq searchReq);
}

View File

@@ -1,54 +1,54 @@
package com.kamco.cd.training.postgres.repository.dataset;
import com.kamco.cd.training.dataset.dto.MapSheetDto;
import com.kamco.cd.training.postgres.entity.MapSheetEntity;
import com.kamco.cd.training.postgres.entity.QMapSheetEntity;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.jpa.impl.JPAQueryFactory;
import java.util.List;
import java.util.Optional;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Repository;
@Repository
@RequiredArgsConstructor
public class MapSheetRepositoryImpl implements MapSheetRepositoryCustom {
private final JPAQueryFactory queryFactory;
private final QMapSheetEntity mapSheet = QMapSheetEntity.mapSheetEntity;
@Override
public Page<MapSheetEntity> findMapSheetList(MapSheetDto.SearchReq searchReq) {
Pageable pageable = searchReq.toPageable();
BooleanBuilder builder = new BooleanBuilder();
// 데이터셋 ID 필터
if (searchReq.getDatasetId() != null) {
builder.and(mapSheet.datasetId.eq(searchReq.getDatasetId()));
}
// 삭제되지 않은 것만
builder.and(mapSheet.deleted.isFalse());
// Entity 직접 조회 (Projections 사용 지양)
List<MapSheetEntity> content =
queryFactory
.selectFrom(mapSheet)
.where(builder)
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.orderBy(mapSheet.createdDttm.desc())
.fetch();
// Count 쿼리 별도 실행 (null safe handling)
long total =
Optional.ofNullable(
queryFactory.select(mapSheet.count()).from(mapSheet).where(builder).fetchOne())
.orElse(0L);
return new PageImpl<>(content, pageable, total);
}
}
package com.kamco.cd.training.postgres.repository.dataset;
import com.kamco.cd.training.dataset.dto.MapSheetDto;
import com.kamco.cd.training.postgres.entity.MapSheetEntity;
import com.kamco.cd.training.postgres.entity.QMapSheetEntity;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.jpa.impl.JPAQueryFactory;
import java.util.List;
import java.util.Optional;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Repository;
@Repository
@RequiredArgsConstructor
public class MapSheetRepositoryImpl implements MapSheetRepositoryCustom {
private final JPAQueryFactory queryFactory;
private final QMapSheetEntity mapSheet = QMapSheetEntity.mapSheetEntity;
@Override
public Page<MapSheetEntity> findMapSheetList(MapSheetDto.SearchReq searchReq) {
Pageable pageable = searchReq.toPageable();
BooleanBuilder builder = new BooleanBuilder();
// 데이터셋 ID 필터
if (searchReq.getDatasetId() != null) {
builder.and(mapSheet.datasetId.eq(searchReq.getDatasetId()));
}
// 삭제되지 않은 것만
builder.and(mapSheet.deleted.isFalse());
// Entity 직접 조회 (Projections 사용 지양)
List<MapSheetEntity> content =
queryFactory
.selectFrom(mapSheet)
.where(builder)
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.orderBy(mapSheet.createdDttm.desc())
.fetch();
// Count 쿼리 별도 실행 (null safe handling)
long total =
Optional.ofNullable(
queryFactory.select(mapSheet.count()).from(mapSheet).where(builder).fetchOne())
.orElse(0L);
return new PageImpl<>(content, pageable, total);
}
}

View File

@@ -1,7 +1,7 @@
package com.kamco.cd.training.postgres.repository.log;
import com.kamco.cd.training.postgres.entity.AuditLogEntity;
import org.springframework.data.jpa.repository.JpaRepository;
public interface AuditLogRepository
extends JpaRepository<AuditLogEntity, Long>, AuditLogRepositoryCustom {}
package com.kamco.cd.training.postgres.repository.log;
import com.kamco.cd.training.postgres.entity.AuditLogEntity;
import org.springframework.data.jpa.repository.JpaRepository;
public interface AuditLogRepository
extends JpaRepository<AuditLogEntity, Long>, AuditLogRepositoryCustom {}

View File

@@ -1,25 +1,25 @@
package com.kamco.cd.training.postgres.repository.log;
import com.kamco.cd.training.log.dto.AuditLogDto;
import java.time.LocalDate;
import org.springframework.data.domain.Page;
public interface AuditLogRepositoryCustom {
Page<AuditLogDto.DailyAuditList> findLogByDaily(
AuditLogDto.searchReq searchReq, LocalDate startDate, LocalDate endDate);
Page<AuditLogDto.MenuAuditList> findLogByMenu(
AuditLogDto.searchReq searchReq, String searchValue);
Page<AuditLogDto.UserAuditList> findLogByAccount(
AuditLogDto.searchReq searchReq, String searchValue);
Page<AuditLogDto.DailyDetail> findLogByDailyResult(
AuditLogDto.searchReq searchReq, LocalDate logDate);
Page<AuditLogDto.MenuDetail> findLogByMenuResult(AuditLogDto.searchReq searchReq, String menuId);
Page<AuditLogDto.UserDetail> findLogByAccountResult(
AuditLogDto.searchReq searchReq, Long accountId);
}
package com.kamco.cd.training.postgres.repository.log;
import com.kamco.cd.training.log.dto.AuditLogDto;
import java.time.LocalDate;
import org.springframework.data.domain.Page;
public interface AuditLogRepositoryCustom {
Page<AuditLogDto.DailyAuditList> findLogByDaily(
AuditLogDto.searchReq searchReq, LocalDate startDate, LocalDate endDate);
Page<AuditLogDto.MenuAuditList> findLogByMenu(
AuditLogDto.searchReq searchReq, String searchValue);
Page<AuditLogDto.UserAuditList> findLogByAccount(
AuditLogDto.searchReq searchReq, String searchValue);
Page<AuditLogDto.DailyDetail> findLogByDailyResult(
AuditLogDto.searchReq searchReq, LocalDate logDate);
Page<AuditLogDto.MenuDetail> findLogByMenuResult(AuditLogDto.searchReq searchReq, String menuId);
Page<AuditLogDto.UserDetail> findLogByAccountResult(
AuditLogDto.searchReq searchReq, Long accountId);
}

View File

@@ -1,442 +1,442 @@
package com.kamco.cd.training.postgres.repository.log;
import static com.kamco.cd.training.postgres.entity.QAuditLogEntity.auditLogEntity;
import static com.kamco.cd.training.postgres.entity.QErrorLogEntity.errorLogEntity;
import static com.kamco.cd.training.postgres.entity.QMemberEntity.memberEntity;
import static com.kamco.cd.training.postgres.entity.QMenuEntity.menuEntity;
import com.kamco.cd.training.log.dto.AuditLogDto;
import com.kamco.cd.training.log.dto.ErrorLogDto;
import com.kamco.cd.training.log.dto.EventStatus;
import com.kamco.cd.training.log.dto.EventType;
import com.kamco.cd.training.postgres.entity.QMenuEntity;
import com.querydsl.core.types.Projections;
import com.querydsl.core.types.dsl.*;
import com.querydsl.jpa.impl.JPAQueryFactory;
import io.micrometer.common.util.StringUtils;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZonedDateTime;
import java.util.List;
import java.util.Objects;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Repository;
@Repository
@RequiredArgsConstructor
public class AuditLogRepositoryImpl implements AuditLogRepositoryCustom {
private final JPAQueryFactory queryFactory;
private final StringExpression NULL_STRING = Expressions.stringTemplate("cast(null as text)");
@Override
public Page<AuditLogDto.DailyAuditList> findLogByDaily(
AuditLogDto.searchReq searchReq, LocalDate startDate, LocalDate endDate) {
StringExpression groupDateTime =
Expressions.stringTemplate("to_char({0}, 'YYYY-MM-DD')", auditLogEntity.createdDate);
Pageable pageable = searchReq.toPageable();
List<AuditLogDto.DailyAuditList> foundContent =
queryFactory
.select(
Projections.constructor(
AuditLogDto.DailyAuditList.class,
readCount().as("readCount"),
cudCount().as("cudCount"),
printCount().as("printCount"),
downloadCount().as("downloadCount"),
auditLogEntity.count().as("totalCount"),
groupDateTime.as("baseDate")))
.from(auditLogEntity)
.where(eventEndedAtBetween(startDate, endDate))
.groupBy(groupDateTime)
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.orderBy(groupDateTime.desc())
.fetch();
Long countQuery =
queryFactory
.select(groupDateTime.countDistinct())
.from(auditLogEntity)
.where(eventEndedAtBetween(startDate, endDate))
.fetchOne();
return new PageImpl<>(foundContent, pageable, countQuery);
}
@Override
public Page<AuditLogDto.MenuAuditList> findLogByMenu(
AuditLogDto.searchReq searchReq, String searchValue) {
Pageable pageable = searchReq.toPageable();
List<AuditLogDto.MenuAuditList> foundContent =
queryFactory
.select(
Projections.constructor(
AuditLogDto.MenuAuditList.class,
auditLogEntity.menuUid.as("menuId"),
menuEntity.menuNm.max().as("menuName"),
readCount().as("readCount"),
cudCount().as("cudCount"),
printCount().as("printCount"),
downloadCount().as("downloadCount"),
auditLogEntity.count().as("totalCount")))
.from(auditLogEntity)
.leftJoin(menuEntity)
.on(auditLogEntity.menuUid.eq(menuEntity.menuUid))
.where(menuNameEquals(searchValue))
.groupBy(auditLogEntity.menuUid)
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.orderBy(auditLogEntity.createdDate.max().desc())
.fetch();
// count query group by 를 지정하면 하나의 row 가 아니라 그룹핑된 여러 row 가 나올 수 있다.
// select query 의 group by 대상의 컬럼을 count query 에선 select distinct 로 처리 한다.
Long countQuery =
queryFactory
.select(auditLogEntity.menuUid.countDistinct())
.from(auditLogEntity)
.leftJoin(menuEntity)
.on(auditLogEntity.menuUid.eq(menuEntity.menuUid))
.where(menuNameEquals(searchValue))
.fetchOne();
return new PageImpl<>(foundContent, pageable, countQuery);
}
@Override
public Page<AuditLogDto.UserAuditList> findLogByAccount(
AuditLogDto.searchReq searchReq, String searchValue) {
Pageable pageable = searchReq.toPageable();
List<AuditLogDto.UserAuditList> foundContent =
queryFactory
.select(
Projections.constructor(
AuditLogDto.UserAuditList.class,
auditLogEntity.userUid.as("accountId"),
memberEntity.employeeNo.as("loginId"),
memberEntity.name.as("username"),
readCount().as("readCount"),
cudCount().as("cudCount"),
printCount().as("printCount"),
downloadCount().as("downloadCount"),
auditLogEntity.count().as("totalCount")))
.from(auditLogEntity)
.leftJoin(memberEntity)
.on(auditLogEntity.userUid.eq(memberEntity.id))
.where(loginIdOrUsernameContains(searchValue))
.groupBy(auditLogEntity.userUid, memberEntity.employeeNo, memberEntity.name)
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
// .orderBy(auditLogEntity.eventEndedAt.max().desc())
.fetch();
Long countQuery =
queryFactory
.select(auditLogEntity.userUid.countDistinct())
.from(auditLogEntity)
.leftJoin(memberEntity)
.on(auditLogEntity.userUid.eq(memberEntity.id))
.where(loginIdOrUsernameContains(searchValue))
.fetchOne();
return new PageImpl<>(foundContent, pageable, countQuery);
}
@Override
public Page<AuditLogDto.DailyDetail> findLogByDailyResult(
AuditLogDto.searchReq searchReq, LocalDate logDate) {
Pageable pageable = searchReq.toPageable();
QMenuEntity parent = new QMenuEntity("parent");
// 1depth menu name
StringExpression parentMenuName =
new CaseBuilder()
.when(parent.menuUid.isNull())
.then(menuEntity.menuNm)
.otherwise(parent.menuNm);
// 2depth menu name
StringExpression menuName =
new CaseBuilder()
.when(parent.menuUid.isNull())
.then(NULL_STRING)
.otherwise(menuEntity.menuNm);
List<AuditLogDto.DailyDetail> foundContent =
queryFactory
.select(
Projections.constructor(
AuditLogDto.DailyDetail.class,
auditLogEntity.id.as("logId"),
memberEntity.name.as("userName"),
memberEntity.employeeNo.as("loginId"),
menuEntity.menuNm.as("menuName"),
auditLogEntity.eventType.as("eventType"),
Projections.constructor(
AuditLogDto.LogDetail.class,
Expressions.constant("한국자산관리공사"), // serviceName
parentMenuName.as("parentMenuName"),
menuName,
menuEntity.menuUrl.as("menuUrl"),
menuEntity.description.as("menuDescription"),
menuEntity.menuOrder.as("sortOrder"),
menuEntity.isUse.as("used"))))
.from(auditLogEntity)
.leftJoin(menuEntity)
.on(auditLogEntity.menuUid.eq(menuEntity.menuUid))
.leftJoin(menuEntity.parent, parent)
.leftJoin(memberEntity)
.on(auditLogEntity.userUid.eq(memberEntity.id))
.where(eventEndedAtEqDate(logDate))
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.orderBy(auditLogEntity.createdDate.desc())
.fetch();
Long countQuery =
queryFactory
.select(auditLogEntity.id.countDistinct())
.from(auditLogEntity)
.leftJoin(menuEntity)
.on(auditLogEntity.menuUid.eq(menuEntity.menuUid))
.leftJoin(menuEntity.parent, parent)
.leftJoin(memberEntity)
.on(auditLogEntity.userUid.eq(memberEntity.id))
.where(eventEndedAtEqDate(logDate))
.fetchOne();
return new PageImpl<>(foundContent, pageable, countQuery);
}
@Override
public Page<AuditLogDto.MenuDetail> findLogByMenuResult(
AuditLogDto.searchReq searchReq, String menuUid) {
Pageable pageable = searchReq.toPageable();
QMenuEntity parent = new QMenuEntity("parent");
// 1depth menu name
StringExpression parentMenuName =
new CaseBuilder()
.when(parent.menuUid.isNull())
.then(menuEntity.menuNm)
.otherwise(parent.menuNm);
// 2depth menu name
StringExpression menuName =
new CaseBuilder()
.when(parent.menuUid.isNull())
.then(NULL_STRING)
.otherwise(menuEntity.menuNm);
List<AuditLogDto.MenuDetail> foundContent =
queryFactory
.select(
Projections.constructor(
AuditLogDto.MenuDetail.class,
auditLogEntity.id.as("logId"),
Expressions.stringTemplate(
"to_char({0}, 'YYYY-MM-DD')", auditLogEntity.createdDate)
.as("logDateTime"), // ??
memberEntity.name.as("userName"),
memberEntity.employeeNo.as("loginId"),
auditLogEntity.eventType.as("eventType"),
Projections.constructor(
AuditLogDto.LogDetail.class,
Expressions.constant("한국자산관리공사"), // serviceName
parentMenuName.as("parentMenuName"),
menuName,
menuEntity.menuUrl.as("menuUrl"),
menuEntity.description.as("menuDescription"),
menuEntity.menuOrder.as("sortOrder"),
menuEntity.isUse.as("used"))))
.from(auditLogEntity)
.leftJoin(menuEntity)
.on(auditLogEntity.menuUid.eq(menuEntity.menuUid))
.leftJoin(menuEntity.parent, parent)
.leftJoin(memberEntity)
.on(auditLogEntity.userUid.eq(memberEntity.id))
.where(menuUidEq(menuUid))
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.orderBy(auditLogEntity.createdDate.desc())
.fetch();
Long countQuery =
queryFactory
.select(auditLogEntity.id.countDistinct())
.from(auditLogEntity)
.leftJoin(menuEntity)
.on(auditLogEntity.menuUid.eq(menuEntity.menuUid))
.leftJoin(menuEntity.parent, parent)
.leftJoin(memberEntity)
.on(auditLogEntity.userUid.eq(memberEntity.id))
.where(menuUidEq(menuUid))
.fetchOne();
return new PageImpl<>(foundContent, pageable, countQuery);
}
@Override
public Page<AuditLogDto.UserDetail> findLogByAccountResult(
AuditLogDto.searchReq searchReq, Long userUid) {
Pageable pageable = searchReq.toPageable();
QMenuEntity parent = new QMenuEntity("parent");
// 1depth menu name
StringExpression parentMenuName =
new CaseBuilder()
.when(parent.menuUid.isNull())
.then(menuEntity.menuNm)
.otherwise(parent.menuNm);
// 2depth menu name
StringExpression menuName =
new CaseBuilder()
.when(parent.menuUid.isNull())
.then(NULL_STRING)
.otherwise(menuEntity.menuNm);
List<AuditLogDto.UserDetail> foundContent =
queryFactory
.select(
Projections.constructor(
AuditLogDto.UserDetail.class,
auditLogEntity.id.as("logId"),
Expressions.stringTemplate(
"to_char({0}, 'YYYY-MM-DD')", auditLogEntity.createdDate)
.as("logDateTime"),
menuEntity.menuNm.as("menuName"),
auditLogEntity.eventType.as("eventType"),
Projections.constructor(
AuditLogDto.LogDetail.class,
Expressions.constant("한국자산관리공사"), // serviceName
parentMenuName.as("parentMenuName"),
menuName,
menuEntity.menuUrl.as("menuUrl"),
menuEntity.description.as("menuDescription"),
menuEntity.menuOrder.as("sortOrder"),
menuEntity.isUse.as("used"))))
.from(auditLogEntity)
.leftJoin(menuEntity)
.on(auditLogEntity.menuUid.eq(menuEntity.menuUid))
.leftJoin(menuEntity.parent, parent)
.leftJoin(memberEntity)
.on(auditLogEntity.userUid.eq(memberEntity.id))
.where(userUidEq(userUid))
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.orderBy(auditLogEntity.createdDate.desc())
.fetch();
Long countQuery =
queryFactory
.select(auditLogEntity.id.countDistinct())
.from(auditLogEntity)
.leftJoin(menuEntity)
.on(auditLogEntity.menuUid.eq(menuEntity.menuUid))
.leftJoin(menuEntity.parent, parent)
.leftJoin(memberEntity)
.on(auditLogEntity.userUid.eq(memberEntity.id))
.where(userUidEq(userUid))
.fetchOne();
return new PageImpl<>(foundContent, pageable, countQuery);
}
private BooleanExpression eventEndedAtBetween(LocalDate startDate, LocalDate endDate) {
if (Objects.isNull(startDate) || Objects.isNull(endDate)) {
return null;
}
LocalDateTime startDateTime = startDate.atStartOfDay();
LocalDateTime endDateTime = endDate.plusDays(1).atStartOfDay();
return auditLogEntity
.createdDate
.goe(ZonedDateTime.from(startDateTime))
.and(auditLogEntity.createdDate.lt(ZonedDateTime.from(endDateTime)));
}
private BooleanExpression menuNameEquals(String searchValue) {
if (StringUtils.isBlank(searchValue)) {
return null;
}
return menuEntity.menuNm.contains(searchValue);
}
private BooleanExpression loginIdOrUsernameContains(String searchValue) {
if (StringUtils.isBlank(searchValue)) {
return null;
}
return memberEntity
.employeeNo
.contains(searchValue)
.or(memberEntity.name.contains(searchValue));
}
private BooleanExpression eventStatusEqFailed() {
return auditLogEntity.eventStatus.eq(EventStatus.FAILED);
}
private BooleanExpression eventTypeEq(EventType eventType) {
if (Objects.isNull(eventType)) {
return null;
}
return auditLogEntity.eventType.eq(eventType);
}
private BooleanExpression errorLevelEq(ErrorLogDto.LogErrorLevel level) {
if (Objects.isNull(level)) {
return null;
}
return errorLogEntity.errorLevel.eq(ErrorLogDto.LogErrorLevel.valueOf(level.name()));
}
private BooleanExpression eventEndedAtEqDate(LocalDate logDate) {
StringExpression eventEndedDate =
Expressions.stringTemplate("to_char({0}, 'YYYY-MM-DD')", auditLogEntity.createdDate);
LocalDateTime comparisonDate = logDate.atStartOfDay();
return eventEndedDate.eq(comparisonDate.toString());
}
private BooleanExpression menuUidEq(String menuUid) {
return auditLogEntity.menuUid.eq(menuUid);
}
private BooleanExpression userUidEq(Long userUid) {
return auditLogEntity.userUid.eq(userUid);
}
private NumberExpression<Integer> readCount() {
return new CaseBuilder()
.when(auditLogEntity.eventType.eq(EventType.READ))
.then(1)
.otherwise(0)
.sum();
}
private NumberExpression<Integer> cudCount() {
return new CaseBuilder()
.when(auditLogEntity.eventType.in(EventType.CREATE, EventType.UPDATE, EventType.DELETE))
.then(1)
.otherwise(0)
.sum();
}
private NumberExpression<Integer> printCount() {
return new CaseBuilder()
.when(auditLogEntity.eventType.eq(EventType.PRINT))
.then(1)
.otherwise(0)
.sum();
}
private NumberExpression<Integer> downloadCount() {
return new CaseBuilder()
.when(auditLogEntity.eventType.eq(EventType.DOWNLOAD))
.then(1)
.otherwise(0)
.sum();
}
}
package com.kamco.cd.training.postgres.repository.log;
import static com.kamco.cd.training.postgres.entity.QAuditLogEntity.auditLogEntity;
import static com.kamco.cd.training.postgres.entity.QErrorLogEntity.errorLogEntity;
import static com.kamco.cd.training.postgres.entity.QMemberEntity.memberEntity;
import static com.kamco.cd.training.postgres.entity.QMenuEntity.menuEntity;
import com.kamco.cd.training.log.dto.AuditLogDto;
import com.kamco.cd.training.log.dto.ErrorLogDto;
import com.kamco.cd.training.log.dto.EventStatus;
import com.kamco.cd.training.log.dto.EventType;
import com.kamco.cd.training.postgres.entity.QMenuEntity;
import com.querydsl.core.types.Projections;
import com.querydsl.core.types.dsl.*;
import com.querydsl.jpa.impl.JPAQueryFactory;
import io.micrometer.common.util.StringUtils;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZonedDateTime;
import java.util.List;
import java.util.Objects;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Repository;
@Repository
@RequiredArgsConstructor
public class AuditLogRepositoryImpl implements AuditLogRepositoryCustom {
private final JPAQueryFactory queryFactory;
private final StringExpression NULL_STRING = Expressions.stringTemplate("cast(null as text)");
@Override
public Page<AuditLogDto.DailyAuditList> findLogByDaily(
AuditLogDto.searchReq searchReq, LocalDate startDate, LocalDate endDate) {
StringExpression groupDateTime =
Expressions.stringTemplate("to_char({0}, 'YYYY-MM-DD')", auditLogEntity.createdDate);
Pageable pageable = searchReq.toPageable();
List<AuditLogDto.DailyAuditList> foundContent =
queryFactory
.select(
Projections.constructor(
AuditLogDto.DailyAuditList.class,
readCount().as("readCount"),
cudCount().as("cudCount"),
printCount().as("printCount"),
downloadCount().as("downloadCount"),
auditLogEntity.count().as("totalCount"),
groupDateTime.as("baseDate")))
.from(auditLogEntity)
.where(eventEndedAtBetween(startDate, endDate))
.groupBy(groupDateTime)
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.orderBy(groupDateTime.desc())
.fetch();
Long countQuery =
queryFactory
.select(groupDateTime.countDistinct())
.from(auditLogEntity)
.where(eventEndedAtBetween(startDate, endDate))
.fetchOne();
return new PageImpl<>(foundContent, pageable, countQuery);
}
@Override
public Page<AuditLogDto.MenuAuditList> findLogByMenu(
AuditLogDto.searchReq searchReq, String searchValue) {
Pageable pageable = searchReq.toPageable();
List<AuditLogDto.MenuAuditList> foundContent =
queryFactory
.select(
Projections.constructor(
AuditLogDto.MenuAuditList.class,
auditLogEntity.menuUid.as("menuId"),
menuEntity.menuNm.max().as("menuName"),
readCount().as("readCount"),
cudCount().as("cudCount"),
printCount().as("printCount"),
downloadCount().as("downloadCount"),
auditLogEntity.count().as("totalCount")))
.from(auditLogEntity)
.leftJoin(menuEntity)
.on(auditLogEntity.menuUid.eq(menuEntity.menuUid))
.where(menuNameEquals(searchValue))
.groupBy(auditLogEntity.menuUid)
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.orderBy(auditLogEntity.createdDate.max().desc())
.fetch();
// count query group by 를 지정하면 하나의 row 가 아니라 그룹핑된 여러 row 가 나올 수 있다.
// select query 의 group by 대상의 컬럼을 count query 에선 select distinct 로 처리 한다.
Long countQuery =
queryFactory
.select(auditLogEntity.menuUid.countDistinct())
.from(auditLogEntity)
.leftJoin(menuEntity)
.on(auditLogEntity.menuUid.eq(menuEntity.menuUid))
.where(menuNameEquals(searchValue))
.fetchOne();
return new PageImpl<>(foundContent, pageable, countQuery);
}
@Override
public Page<AuditLogDto.UserAuditList> findLogByAccount(
AuditLogDto.searchReq searchReq, String searchValue) {
Pageable pageable = searchReq.toPageable();
List<AuditLogDto.UserAuditList> foundContent =
queryFactory
.select(
Projections.constructor(
AuditLogDto.UserAuditList.class,
auditLogEntity.userUid.as("accountId"),
memberEntity.employeeNo.as("loginId"),
memberEntity.name.as("username"),
readCount().as("readCount"),
cudCount().as("cudCount"),
printCount().as("printCount"),
downloadCount().as("downloadCount"),
auditLogEntity.count().as("totalCount")))
.from(auditLogEntity)
.leftJoin(memberEntity)
.on(auditLogEntity.userUid.eq(memberEntity.id))
.where(loginIdOrUsernameContains(searchValue))
.groupBy(auditLogEntity.userUid, memberEntity.employeeNo, memberEntity.name)
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
// .orderBy(auditLogEntity.eventEndedAt.max().desc())
.fetch();
Long countQuery =
queryFactory
.select(auditLogEntity.userUid.countDistinct())
.from(auditLogEntity)
.leftJoin(memberEntity)
.on(auditLogEntity.userUid.eq(memberEntity.id))
.where(loginIdOrUsernameContains(searchValue))
.fetchOne();
return new PageImpl<>(foundContent, pageable, countQuery);
}
@Override
public Page<AuditLogDto.DailyDetail> findLogByDailyResult(
AuditLogDto.searchReq searchReq, LocalDate logDate) {
Pageable pageable = searchReq.toPageable();
QMenuEntity parent = new QMenuEntity("parent");
// 1depth menu name
StringExpression parentMenuName =
new CaseBuilder()
.when(parent.menuUid.isNull())
.then(menuEntity.menuNm)
.otherwise(parent.menuNm);
// 2depth menu name
StringExpression menuName =
new CaseBuilder()
.when(parent.menuUid.isNull())
.then(NULL_STRING)
.otherwise(menuEntity.menuNm);
List<AuditLogDto.DailyDetail> foundContent =
queryFactory
.select(
Projections.constructor(
AuditLogDto.DailyDetail.class,
auditLogEntity.id.as("logId"),
memberEntity.name.as("userName"),
memberEntity.employeeNo.as("loginId"),
menuEntity.menuNm.as("menuName"),
auditLogEntity.eventType.as("eventType"),
Projections.constructor(
AuditLogDto.LogDetail.class,
Expressions.constant("한국자산관리공사"), // serviceName
parentMenuName.as("parentMenuName"),
menuName,
menuEntity.menuUrl.as("menuUrl"),
menuEntity.description.as("menuDescription"),
menuEntity.menuOrder.as("sortOrder"),
menuEntity.isUse.as("used"))))
.from(auditLogEntity)
.leftJoin(menuEntity)
.on(auditLogEntity.menuUid.eq(menuEntity.menuUid))
.leftJoin(menuEntity.parent, parent)
.leftJoin(memberEntity)
.on(auditLogEntity.userUid.eq(memberEntity.id))
.where(eventEndedAtEqDate(logDate))
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.orderBy(auditLogEntity.createdDate.desc())
.fetch();
Long countQuery =
queryFactory
.select(auditLogEntity.id.countDistinct())
.from(auditLogEntity)
.leftJoin(menuEntity)
.on(auditLogEntity.menuUid.eq(menuEntity.menuUid))
.leftJoin(menuEntity.parent, parent)
.leftJoin(memberEntity)
.on(auditLogEntity.userUid.eq(memberEntity.id))
.where(eventEndedAtEqDate(logDate))
.fetchOne();
return new PageImpl<>(foundContent, pageable, countQuery);
}
@Override
public Page<AuditLogDto.MenuDetail> findLogByMenuResult(
AuditLogDto.searchReq searchReq, String menuUid) {
Pageable pageable = searchReq.toPageable();
QMenuEntity parent = new QMenuEntity("parent");
// 1depth menu name
StringExpression parentMenuName =
new CaseBuilder()
.when(parent.menuUid.isNull())
.then(menuEntity.menuNm)
.otherwise(parent.menuNm);
// 2depth menu name
StringExpression menuName =
new CaseBuilder()
.when(parent.menuUid.isNull())
.then(NULL_STRING)
.otherwise(menuEntity.menuNm);
List<AuditLogDto.MenuDetail> foundContent =
queryFactory
.select(
Projections.constructor(
AuditLogDto.MenuDetail.class,
auditLogEntity.id.as("logId"),
Expressions.stringTemplate(
"to_char({0}, 'YYYY-MM-DD')", auditLogEntity.createdDate)
.as("logDateTime"), // ??
memberEntity.name.as("userName"),
memberEntity.employeeNo.as("loginId"),
auditLogEntity.eventType.as("eventType"),
Projections.constructor(
AuditLogDto.LogDetail.class,
Expressions.constant("한국자산관리공사"), // serviceName
parentMenuName.as("parentMenuName"),
menuName,
menuEntity.menuUrl.as("menuUrl"),
menuEntity.description.as("menuDescription"),
menuEntity.menuOrder.as("sortOrder"),
menuEntity.isUse.as("used"))))
.from(auditLogEntity)
.leftJoin(menuEntity)
.on(auditLogEntity.menuUid.eq(menuEntity.menuUid))
.leftJoin(menuEntity.parent, parent)
.leftJoin(memberEntity)
.on(auditLogEntity.userUid.eq(memberEntity.id))
.where(menuUidEq(menuUid))
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.orderBy(auditLogEntity.createdDate.desc())
.fetch();
Long countQuery =
queryFactory
.select(auditLogEntity.id.countDistinct())
.from(auditLogEntity)
.leftJoin(menuEntity)
.on(auditLogEntity.menuUid.eq(menuEntity.menuUid))
.leftJoin(menuEntity.parent, parent)
.leftJoin(memberEntity)
.on(auditLogEntity.userUid.eq(memberEntity.id))
.where(menuUidEq(menuUid))
.fetchOne();
return new PageImpl<>(foundContent, pageable, countQuery);
}
@Override
public Page<AuditLogDto.UserDetail> findLogByAccountResult(
AuditLogDto.searchReq searchReq, Long userUid) {
Pageable pageable = searchReq.toPageable();
QMenuEntity parent = new QMenuEntity("parent");
// 1depth menu name
StringExpression parentMenuName =
new CaseBuilder()
.when(parent.menuUid.isNull())
.then(menuEntity.menuNm)
.otherwise(parent.menuNm);
// 2depth menu name
StringExpression menuName =
new CaseBuilder()
.when(parent.menuUid.isNull())
.then(NULL_STRING)
.otherwise(menuEntity.menuNm);
List<AuditLogDto.UserDetail> foundContent =
queryFactory
.select(
Projections.constructor(
AuditLogDto.UserDetail.class,
auditLogEntity.id.as("logId"),
Expressions.stringTemplate(
"to_char({0}, 'YYYY-MM-DD')", auditLogEntity.createdDate)
.as("logDateTime"),
menuEntity.menuNm.as("menuName"),
auditLogEntity.eventType.as("eventType"),
Projections.constructor(
AuditLogDto.LogDetail.class,
Expressions.constant("한국자산관리공사"), // serviceName
parentMenuName.as("parentMenuName"),
menuName,
menuEntity.menuUrl.as("menuUrl"),
menuEntity.description.as("menuDescription"),
menuEntity.menuOrder.as("sortOrder"),
menuEntity.isUse.as("used"))))
.from(auditLogEntity)
.leftJoin(menuEntity)
.on(auditLogEntity.menuUid.eq(menuEntity.menuUid))
.leftJoin(menuEntity.parent, parent)
.leftJoin(memberEntity)
.on(auditLogEntity.userUid.eq(memberEntity.id))
.where(userUidEq(userUid))
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.orderBy(auditLogEntity.createdDate.desc())
.fetch();
Long countQuery =
queryFactory
.select(auditLogEntity.id.countDistinct())
.from(auditLogEntity)
.leftJoin(menuEntity)
.on(auditLogEntity.menuUid.eq(menuEntity.menuUid))
.leftJoin(menuEntity.parent, parent)
.leftJoin(memberEntity)
.on(auditLogEntity.userUid.eq(memberEntity.id))
.where(userUidEq(userUid))
.fetchOne();
return new PageImpl<>(foundContent, pageable, countQuery);
}
private BooleanExpression eventEndedAtBetween(LocalDate startDate, LocalDate endDate) {
if (Objects.isNull(startDate) || Objects.isNull(endDate)) {
return null;
}
LocalDateTime startDateTime = startDate.atStartOfDay();
LocalDateTime endDateTime = endDate.plusDays(1).atStartOfDay();
return auditLogEntity
.createdDate
.goe(ZonedDateTime.from(startDateTime))
.and(auditLogEntity.createdDate.lt(ZonedDateTime.from(endDateTime)));
}
private BooleanExpression menuNameEquals(String searchValue) {
if (StringUtils.isBlank(searchValue)) {
return null;
}
return menuEntity.menuNm.contains(searchValue);
}
private BooleanExpression loginIdOrUsernameContains(String searchValue) {
if (StringUtils.isBlank(searchValue)) {
return null;
}
return memberEntity
.employeeNo
.contains(searchValue)
.or(memberEntity.name.contains(searchValue));
}
private BooleanExpression eventStatusEqFailed() {
return auditLogEntity.eventStatus.eq(EventStatus.FAILED);
}
private BooleanExpression eventTypeEq(EventType eventType) {
if (Objects.isNull(eventType)) {
return null;
}
return auditLogEntity.eventType.eq(eventType);
}
private BooleanExpression errorLevelEq(ErrorLogDto.LogErrorLevel level) {
if (Objects.isNull(level)) {
return null;
}
return errorLogEntity.errorLevel.eq(ErrorLogDto.LogErrorLevel.valueOf(level.name()));
}
private BooleanExpression eventEndedAtEqDate(LocalDate logDate) {
StringExpression eventEndedDate =
Expressions.stringTemplate("to_char({0}, 'YYYY-MM-DD')", auditLogEntity.createdDate);
LocalDateTime comparisonDate = logDate.atStartOfDay();
return eventEndedDate.eq(comparisonDate.toString());
}
private BooleanExpression menuUidEq(String menuUid) {
return auditLogEntity.menuUid.eq(menuUid);
}
private BooleanExpression userUidEq(Long userUid) {
return auditLogEntity.userUid.eq(userUid);
}
private NumberExpression<Integer> readCount() {
return new CaseBuilder()
.when(auditLogEntity.eventType.eq(EventType.READ))
.then(1)
.otherwise(0)
.sum();
}
private NumberExpression<Integer> cudCount() {
return new CaseBuilder()
.when(auditLogEntity.eventType.in(EventType.CREATE, EventType.UPDATE, EventType.DELETE))
.then(1)
.otherwise(0)
.sum();
}
private NumberExpression<Integer> printCount() {
return new CaseBuilder()
.when(auditLogEntity.eventType.eq(EventType.PRINT))
.then(1)
.otherwise(0)
.sum();
}
private NumberExpression<Integer> downloadCount() {
return new CaseBuilder()
.when(auditLogEntity.eventType.eq(EventType.DOWNLOAD))
.then(1)
.otherwise(0)
.sum();
}
}

View File

@@ -1,7 +1,7 @@
package com.kamco.cd.training.postgres.repository.log;
import com.kamco.cd.training.postgres.entity.ErrorLogEntity;
import org.springframework.data.jpa.repository.JpaRepository;
public interface ErrorLogRepository
extends JpaRepository<ErrorLogEntity, Long>, ErrorLogRepositoryCustom {}
package com.kamco.cd.training.postgres.repository.log;
import com.kamco.cd.training.postgres.entity.ErrorLogEntity;
import org.springframework.data.jpa.repository.JpaRepository;
public interface ErrorLogRepository
extends JpaRepository<ErrorLogEntity, Long>, ErrorLogRepositoryCustom {}

View File

@@ -1,8 +1,8 @@
package com.kamco.cd.training.postgres.repository.log;
import com.kamco.cd.training.log.dto.ErrorLogDto;
import org.springframework.data.domain.Page;
public interface ErrorLogRepositoryCustom {
public Page<ErrorLogDto.Basic> findLogByError(ErrorLogDto.ErrorSearchReq searchReq);
}
package com.kamco.cd.training.postgres.repository.log;
import com.kamco.cd.training.log.dto.ErrorLogDto;
import org.springframework.data.domain.Page;
public interface ErrorLogRepositoryCustom {
public Page<ErrorLogDto.Basic> findLogByError(ErrorLogDto.ErrorSearchReq searchReq);
}

View File

@@ -1,122 +1,122 @@
package com.kamco.cd.training.postgres.repository.log;
import static com.kamco.cd.training.postgres.entity.QAuditLogEntity.auditLogEntity;
import static com.kamco.cd.training.postgres.entity.QErrorLogEntity.errorLogEntity;
import static com.kamco.cd.training.postgres.entity.QMemberEntity.memberEntity;
import static com.kamco.cd.training.postgres.entity.QMenuEntity.menuEntity;
import com.kamco.cd.training.log.dto.ErrorLogDto;
import com.kamco.cd.training.log.dto.EventStatus;
import com.kamco.cd.training.log.dto.EventType;
import com.querydsl.core.types.Projections;
import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.core.types.dsl.Expressions;
import com.querydsl.core.types.dsl.StringExpression;
import com.querydsl.jpa.impl.JPAQueryFactory;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZonedDateTime;
import java.util.List;
import java.util.Objects;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Repository;
@Repository
@RequiredArgsConstructor
public class ErrorLogRepositoryImpl implements ErrorLogRepositoryCustom {
private final JPAQueryFactory queryFactory;
private final StringExpression NULL_STRING = Expressions.stringTemplate("cast(null as text)");
@Override
public Page<ErrorLogDto.Basic> findLogByError(ErrorLogDto.ErrorSearchReq searchReq) {
Pageable pageable = searchReq.toPageable();
List<ErrorLogDto.Basic> foundContent =
queryFactory
.select(
Projections.constructor(
ErrorLogDto.Basic.class,
errorLogEntity.id.as("logId"),
Expressions.stringTemplate("{0}", "한국자산관리공사"), // serviceName
menuEntity.menuNm.as("menuName"),
memberEntity.employeeNo.as("loginId"),
memberEntity.name.as("userName"),
errorLogEntity.errorType.as("eventType"),
errorLogEntity.errorMessage.as(
"errorName"), // 기존에는 errorName 값이 있었는데 신규 테이블에는 없음. 에러 메세지와 동일
errorLogEntity.errorLevel.as("errorLevel"),
errorLogEntity.errorCode.as("errorCode"),
errorLogEntity.errorMessage.as("errorMessage"),
errorLogEntity.stackTrace.as("errorDetail"),
Expressions.stringTemplate(
"to_char({0}, 'YYYY-MM-DD')", errorLogEntity.createdDate)))
.from(errorLogEntity)
.leftJoin(auditLogEntity)
.on(errorLogEntity.id.eq(auditLogEntity.errorLogUid))
.leftJoin(menuEntity)
.on(auditLogEntity.menuUid.eq(menuEntity.menuUid))
.leftJoin(memberEntity)
.on(errorLogEntity.handlerUid.eq(memberEntity.id))
.where(
eventStatusEqFailed(),
eventEndedAtBetween(searchReq.getStartDate(), searchReq.getEndDate()),
eventTypeEq(searchReq.getEventType()),
errorLevelEq(searchReq.getErrorLevel()))
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.orderBy(errorLogEntity.createdDate.desc())
.fetch();
Long countQuery =
queryFactory
.select(errorLogEntity.id.countDistinct())
.from(errorLogEntity)
.leftJoin(auditLogEntity)
.on(errorLogEntity.id.eq(auditLogEntity.errorLogUid))
.leftJoin(menuEntity)
.on(auditLogEntity.menuUid.eq(menuEntity.menuUid))
.leftJoin(memberEntity)
.on(errorLogEntity.handlerUid.eq(memberEntity.id))
.where(
eventStatusEqFailed(),
eventEndedAtBetween(searchReq.getStartDate(), searchReq.getEndDate()),
eventTypeEq(searchReq.getEventType()),
errorLevelEq(searchReq.getErrorLevel()))
.fetchOne();
return new PageImpl<>(foundContent, pageable, countQuery);
}
private BooleanExpression eventEndedAtBetween(LocalDate startDate, LocalDate endDate) {
if (Objects.isNull(startDate) || Objects.isNull(endDate)) {
return null;
}
LocalDateTime startDateTime = startDate.atStartOfDay();
LocalDateTime endDateTime = endDate.plusDays(1).atStartOfDay();
return auditLogEntity
.createdDate
.goe(ZonedDateTime.from(startDateTime))
.and(auditLogEntity.createdDate.lt(ZonedDateTime.from(endDateTime)));
}
private BooleanExpression eventStatusEqFailed() {
return auditLogEntity.eventStatus.eq(EventStatus.FAILED);
}
private BooleanExpression eventTypeEq(EventType eventType) {
if (Objects.isNull(eventType)) {
return null;
}
return auditLogEntity.eventType.eq(eventType);
}
private BooleanExpression errorLevelEq(ErrorLogDto.LogErrorLevel level) {
if (Objects.isNull(level)) {
return null;
}
return errorLogEntity.errorLevel.eq(ErrorLogDto.LogErrorLevel.valueOf(level.name()));
}
}
package com.kamco.cd.training.postgres.repository.log;
import static com.kamco.cd.training.postgres.entity.QAuditLogEntity.auditLogEntity;
import static com.kamco.cd.training.postgres.entity.QErrorLogEntity.errorLogEntity;
import static com.kamco.cd.training.postgres.entity.QMemberEntity.memberEntity;
import static com.kamco.cd.training.postgres.entity.QMenuEntity.menuEntity;
import com.kamco.cd.training.log.dto.ErrorLogDto;
import com.kamco.cd.training.log.dto.EventStatus;
import com.kamco.cd.training.log.dto.EventType;
import com.querydsl.core.types.Projections;
import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.core.types.dsl.Expressions;
import com.querydsl.core.types.dsl.StringExpression;
import com.querydsl.jpa.impl.JPAQueryFactory;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZonedDateTime;
import java.util.List;
import java.util.Objects;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Repository;
@Repository
@RequiredArgsConstructor
public class ErrorLogRepositoryImpl implements ErrorLogRepositoryCustom {
private final JPAQueryFactory queryFactory;
private final StringExpression NULL_STRING = Expressions.stringTemplate("cast(null as text)");
@Override
public Page<ErrorLogDto.Basic> findLogByError(ErrorLogDto.ErrorSearchReq searchReq) {
Pageable pageable = searchReq.toPageable();
List<ErrorLogDto.Basic> foundContent =
queryFactory
.select(
Projections.constructor(
ErrorLogDto.Basic.class,
errorLogEntity.id.as("logId"),
Expressions.stringTemplate("{0}", "한국자산관리공사"), // serviceName
menuEntity.menuNm.as("menuName"),
memberEntity.employeeNo.as("loginId"),
memberEntity.name.as("userName"),
errorLogEntity.errorType.as("eventType"),
errorLogEntity.errorMessage.as(
"errorName"), // 기존에는 errorName 값이 있었는데 신규 테이블에는 없음. 에러 메세지와 동일
errorLogEntity.errorLevel.as("errorLevel"),
errorLogEntity.errorCode.as("errorCode"),
errorLogEntity.errorMessage.as("errorMessage"),
errorLogEntity.stackTrace.as("errorDetail"),
Expressions.stringTemplate(
"to_char({0}, 'YYYY-MM-DD')", errorLogEntity.createdDate)))
.from(errorLogEntity)
.leftJoin(auditLogEntity)
.on(errorLogEntity.id.eq(auditLogEntity.errorLogUid))
.leftJoin(menuEntity)
.on(auditLogEntity.menuUid.eq(menuEntity.menuUid))
.leftJoin(memberEntity)
.on(errorLogEntity.handlerUid.eq(memberEntity.id))
.where(
eventStatusEqFailed(),
eventEndedAtBetween(searchReq.getStartDate(), searchReq.getEndDate()),
eventTypeEq(searchReq.getEventType()),
errorLevelEq(searchReq.getErrorLevel()))
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.orderBy(errorLogEntity.createdDate.desc())
.fetch();
Long countQuery =
queryFactory
.select(errorLogEntity.id.countDistinct())
.from(errorLogEntity)
.leftJoin(auditLogEntity)
.on(errorLogEntity.id.eq(auditLogEntity.errorLogUid))
.leftJoin(menuEntity)
.on(auditLogEntity.menuUid.eq(menuEntity.menuUid))
.leftJoin(memberEntity)
.on(errorLogEntity.handlerUid.eq(memberEntity.id))
.where(
eventStatusEqFailed(),
eventEndedAtBetween(searchReq.getStartDate(), searchReq.getEndDate()),
eventTypeEq(searchReq.getEventType()),
errorLevelEq(searchReq.getErrorLevel()))
.fetchOne();
return new PageImpl<>(foundContent, pageable, countQuery);
}
private BooleanExpression eventEndedAtBetween(LocalDate startDate, LocalDate endDate) {
if (Objects.isNull(startDate) || Objects.isNull(endDate)) {
return null;
}
LocalDateTime startDateTime = startDate.atStartOfDay();
LocalDateTime endDateTime = endDate.plusDays(1).atStartOfDay();
return auditLogEntity
.createdDate
.goe(ZonedDateTime.from(startDateTime))
.and(auditLogEntity.createdDate.lt(ZonedDateTime.from(endDateTime)));
}
private BooleanExpression eventStatusEqFailed() {
return auditLogEntity.eventStatus.eq(EventStatus.FAILED);
}
private BooleanExpression eventTypeEq(EventType eventType) {
if (Objects.isNull(eventType)) {
return null;
}
return auditLogEntity.eventType.eq(eventType);
}
private BooleanExpression errorLevelEq(ErrorLogDto.LogErrorLevel level) {
if (Objects.isNull(level)) {
return null;
}
return errorLogEntity.errorLevel.eq(ErrorLogDto.LogErrorLevel.valueOf(level.name()));
}
}

View File

@@ -1,50 +1,50 @@
package com.kamco.cd.training.postgres.repository.members;
import com.kamco.cd.training.postgres.entity.AuthRefreshTokenEntity;
import com.kamco.cd.training.postgres.entity.QAuthRefreshTokenEntity;
import com.querydsl.jpa.impl.JPAQueryFactory;
import java.time.ZonedDateTime;
import java.util.Optional;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;
@Repository
@RequiredArgsConstructor
public class AuthRefreshTokenImpl implements AuthRefreshTokenRepositoryCustom {
private final JPAQueryFactory queryFactory;
private final QAuthRefreshTokenEntity tokenEntity =
QAuthRefreshTokenEntity.authRefreshTokenEntity;
/**
* subject로 조회
*
* @param subject 사용자 식별(UUID)
* @return
*/
@Override
public Optional<AuthRefreshTokenEntity> findBySubject(String subject) {
return Optional.ofNullable(
queryFactory.selectFrom(tokenEntity).where(tokenEntity.subject.eq(subject)).fetchOne());
}
/**
* 토큰 정보 조회
*
* @param subject
* @param now
* @return
*/
@Override
public Optional<AuthRefreshTokenEntity> findBySubjectAndRevokedDttmIsNullAndExpiresDttmAfter(
String subject, ZonedDateTime now) {
return Optional.ofNullable(
queryFactory
.selectFrom(tokenEntity)
.where(
tokenEntity.subject.eq(subject),
tokenEntity.revokedDttm.isNull(),
tokenEntity.expiresDttm.gt(now))
.fetchOne());
}
}
package com.kamco.cd.training.postgres.repository.members;
import com.kamco.cd.training.postgres.entity.AuthRefreshTokenEntity;
import com.kamco.cd.training.postgres.entity.QAuthRefreshTokenEntity;
import com.querydsl.jpa.impl.JPAQueryFactory;
import java.time.ZonedDateTime;
import java.util.Optional;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;
@Repository
@RequiredArgsConstructor
public class AuthRefreshTokenImpl implements AuthRefreshTokenRepositoryCustom {
private final JPAQueryFactory queryFactory;
private final QAuthRefreshTokenEntity tokenEntity =
QAuthRefreshTokenEntity.authRefreshTokenEntity;
/**
* subject로 조회
*
* @param subject 사용자 식별(UUID)
* @return
*/
@Override
public Optional<AuthRefreshTokenEntity> findBySubject(String subject) {
return Optional.ofNullable(
queryFactory.selectFrom(tokenEntity).where(tokenEntity.subject.eq(subject)).fetchOne());
}
/**
* 토큰 정보 조회
*
* @param subject
* @param now
* @return
*/
@Override
public Optional<AuthRefreshTokenEntity> findBySubjectAndRevokedDttmIsNullAndExpiresDttmAfter(
String subject, ZonedDateTime now) {
return Optional.ofNullable(
queryFactory
.selectFrom(tokenEntity)
.where(
tokenEntity.subject.eq(subject),
tokenEntity.revokedDttm.isNull(),
tokenEntity.expiresDttm.gt(now))
.fetchOne());
}
}

View File

@@ -1,7 +1,7 @@
package com.kamco.cd.training.postgres.repository.members;
import com.kamco.cd.training.postgres.entity.AuthRefreshTokenEntity;
import org.springframework.data.jpa.repository.JpaRepository;
public interface AuthRefreshTokenRepository
extends JpaRepository<AuthRefreshTokenEntity, Long>, AuthRefreshTokenRepositoryCustom {}
package com.kamco.cd.training.postgres.repository.members;
import com.kamco.cd.training.postgres.entity.AuthRefreshTokenEntity;
import org.springframework.data.jpa.repository.JpaRepository;
public interface AuthRefreshTokenRepository
extends JpaRepository<AuthRefreshTokenEntity, Long>, AuthRefreshTokenRepositoryCustom {}

View File

@@ -1,12 +1,12 @@
package com.kamco.cd.training.postgres.repository.members;
import com.kamco.cd.training.postgres.entity.AuthRefreshTokenEntity;
import java.time.ZonedDateTime;
import java.util.Optional;
public interface AuthRefreshTokenRepositoryCustom {
Optional<AuthRefreshTokenEntity> findBySubject(String subject);
Optional<AuthRefreshTokenEntity> findBySubjectAndRevokedDttmIsNullAndExpiresDttmAfter(
String subject, ZonedDateTime now);
}
package com.kamco.cd.training.postgres.repository.members;
import com.kamco.cd.training.postgres.entity.AuthRefreshTokenEntity;
import java.time.ZonedDateTime;
import java.util.Optional;
public interface AuthRefreshTokenRepositoryCustom {
Optional<AuthRefreshTokenEntity> findBySubject(String subject);
Optional<AuthRefreshTokenEntity> findBySubjectAndRevokedDttmIsNullAndExpiresDttmAfter(
String subject, ZonedDateTime now);
}

View File

@@ -1,7 +1,7 @@
package com.kamco.cd.training.postgres.repository.members;
import com.kamco.cd.training.postgres.entity.MemberEntity;
import org.springframework.data.jpa.repository.JpaRepository;
public interface MembersRepository
extends JpaRepository<MemberEntity, Long>, MembersRepositoryCustom {}
package com.kamco.cd.training.postgres.repository.members;
import com.kamco.cd.training.postgres.entity.MemberEntity;
import org.springframework.data.jpa.repository.JpaRepository;
public interface MembersRepository
extends JpaRepository<MemberEntity, Long>, MembersRepositoryCustom {}

View File

@@ -1,21 +1,21 @@
package com.kamco.cd.training.postgres.repository.members;
import com.kamco.cd.training.members.dto.MembersDto;
import com.kamco.cd.training.postgres.entity.MemberEntity;
import java.util.Optional;
import java.util.UUID;
import org.springframework.data.domain.Page;
public interface MembersRepositoryCustom {
boolean existsByUserId(String userId);
boolean existsByEmployeeNo(String employeeNo);
Optional<MemberEntity> findByEmployeeNo(String employeeNo);
Optional<MemberEntity> findByUserId(String userId);
Optional<MemberEntity> findByUUID(UUID uuid);
Page<MemberEntity> findByMembers(MembersDto.SearchReq searchReq);
}
package com.kamco.cd.training.postgres.repository.members;
import com.kamco.cd.training.members.dto.MembersDto;
import com.kamco.cd.training.postgres.entity.MemberEntity;
import java.util.Optional;
import java.util.UUID;
import org.springframework.data.domain.Page;
public interface MembersRepositoryCustom {
boolean existsByUserId(String userId);
boolean existsByEmployeeNo(String employeeNo);
Optional<MemberEntity> findByEmployeeNo(String employeeNo);
Optional<MemberEntity> findByUserId(String userId);
Optional<MemberEntity> findByUUID(UUID uuid);
Page<MemberEntity> findByMembers(MembersDto.SearchReq searchReq);
}

View File

@@ -1,151 +1,151 @@
package com.kamco.cd.training.postgres.repository.members;
import com.kamco.cd.training.members.dto.MembersDto;
import com.kamco.cd.training.postgres.entity.MemberEntity;
import com.kamco.cd.training.postgres.entity.QMemberEntity;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.jpa.impl.JPAQueryFactory;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.support.QuerydslRepositorySupport;
import org.springframework.stereotype.Repository;
@Repository
public class MembersRepositoryImpl extends QuerydslRepositorySupport
implements MembersRepositoryCustom {
private final JPAQueryFactory queryFactory;
private final QMemberEntity memberEntity = QMemberEntity.memberEntity;
public MembersRepositoryImpl(JPAQueryFactory queryFactory) {
super(MemberEntity.class);
this.queryFactory = queryFactory;
}
/**
* 사용자 ID 조회
*
* @param userId
* @return
*/
@Override
public boolean existsByUserId(String userId) {
return queryFactory
.selectOne()
.from(memberEntity)
.where(memberEntity.userId.eq(userId))
.fetchFirst()
!= null;
}
/**
* 사용자 사번 조회
*
* @param employeeNo
* @return
*/
@Override
public boolean existsByEmployeeNo(String employeeNo) {
return queryFactory
.selectOne()
.from(memberEntity)
.where(memberEntity.employeeNo.eq(employeeNo))
.fetchFirst()
!= null;
}
/**
* 사용자 조회 user id
*
* @param userId
* @return
*/
@Override
public Optional<MemberEntity> findByUserId(String userId) {
return Optional.ofNullable(
queryFactory.selectFrom(memberEntity).where(memberEntity.userId.eq(userId)).fetchOne());
}
/**
* 사용자 조회 employeed no
*
* @param employeeNo
* @return
*/
@Override
public Optional<MemberEntity> findByEmployeeNo(String employeeNo) {
return Optional.ofNullable(
queryFactory
.selectFrom(memberEntity)
.where(memberEntity.employeeNo.eq(employeeNo))
.fetchOne());
}
/**
* 회원정보 목록 조회
*
* @param searchReq
* @return
*/
@Override
public Page<MemberEntity> findByMembers(MembersDto.SearchReq searchReq) {
Pageable pageable = searchReq.toPageable();
BooleanBuilder builder = new BooleanBuilder();
// 검색어
if (StringUtils.isNotBlank(searchReq.getKeyword())) {
String contains = "%" + searchReq.getKeyword() + "%";
builder.and(
memberEntity
.name
.likeIgnoreCase(contains)
.or(memberEntity.userId.likeIgnoreCase(contains))
.or(memberEntity.employeeNo.likeIgnoreCase(contains)));
}
// 권한
if (StringUtils.isNotBlank(searchReq.getUserRole())) {
builder.and(memberEntity.userRole.eq(searchReq.getUserRole()));
}
// Entity 직접 조회 (Projections 사용 지양)
List<MemberEntity> content =
queryFactory
.selectFrom(memberEntity)
.where(builder)
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.orderBy(memberEntity.createdDttm.desc())
.fetch();
// Count 쿼리 별도 실행 (null safe handling)
long total =
Optional.ofNullable(
queryFactory
.select(memberEntity.count())
.from(memberEntity)
.where(builder)
.fetchOne())
.orElse(0L);
return new PageImpl<>(content, pageable, total);
}
/**
* 사용자 ID 조회 UUID
*
* @param uuid
* @return
*/
@Override
public Optional<MemberEntity> findByUUID(UUID uuid) {
return Optional.ofNullable(
queryFactory.selectFrom(memberEntity).where(memberEntity.uuid.eq(uuid)).fetchOne());
}
}
package com.kamco.cd.training.postgres.repository.members;
import com.kamco.cd.training.members.dto.MembersDto;
import com.kamco.cd.training.postgres.entity.MemberEntity;
import com.kamco.cd.training.postgres.entity.QMemberEntity;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.jpa.impl.JPAQueryFactory;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.support.QuerydslRepositorySupport;
import org.springframework.stereotype.Repository;
@Repository
public class MembersRepositoryImpl extends QuerydslRepositorySupport
implements MembersRepositoryCustom {
private final JPAQueryFactory queryFactory;
private final QMemberEntity memberEntity = QMemberEntity.memberEntity;
public MembersRepositoryImpl(JPAQueryFactory queryFactory) {
super(MemberEntity.class);
this.queryFactory = queryFactory;
}
/**
* 사용자 ID 조회
*
* @param userId
* @return
*/
@Override
public boolean existsByUserId(String userId) {
return queryFactory
.selectOne()
.from(memberEntity)
.where(memberEntity.userId.eq(userId))
.fetchFirst()
!= null;
}
/**
* 사용자 사번 조회
*
* @param employeeNo
* @return
*/
@Override
public boolean existsByEmployeeNo(String employeeNo) {
return queryFactory
.selectOne()
.from(memberEntity)
.where(memberEntity.employeeNo.eq(employeeNo))
.fetchFirst()
!= null;
}
/**
* 사용자 조회 user id
*
* @param userId
* @return
*/
@Override
public Optional<MemberEntity> findByUserId(String userId) {
return Optional.ofNullable(
queryFactory.selectFrom(memberEntity).where(memberEntity.userId.eq(userId)).fetchOne());
}
/**
* 사용자 조회 employeed no
*
* @param employeeNo
* @return
*/
@Override
public Optional<MemberEntity> findByEmployeeNo(String employeeNo) {
return Optional.ofNullable(
queryFactory
.selectFrom(memberEntity)
.where(memberEntity.employeeNo.eq(employeeNo))
.fetchOne());
}
/**
* 회원정보 목록 조회
*
* @param searchReq
* @return
*/
@Override
public Page<MemberEntity> findByMembers(MembersDto.SearchReq searchReq) {
Pageable pageable = searchReq.toPageable();
BooleanBuilder builder = new BooleanBuilder();
// 검색어
if (StringUtils.isNotBlank(searchReq.getKeyword())) {
String contains = "%" + searchReq.getKeyword() + "%";
builder.and(
memberEntity
.name
.likeIgnoreCase(contains)
.or(memberEntity.userId.likeIgnoreCase(contains))
.or(memberEntity.employeeNo.likeIgnoreCase(contains)));
}
// 권한
if (StringUtils.isNotBlank(searchReq.getUserRole())) {
builder.and(memberEntity.userRole.eq(searchReq.getUserRole()));
}
// Entity 직접 조회 (Projections 사용 지양)
List<MemberEntity> content =
queryFactory
.selectFrom(memberEntity)
.where(builder)
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.orderBy(memberEntity.createdDttm.desc())
.fetch();
// Count 쿼리 별도 실행 (null safe handling)
long total =
Optional.ofNullable(
queryFactory
.select(memberEntity.count())
.from(memberEntity)
.where(builder)
.fetchOne())
.orElse(0L);
return new PageImpl<>(content, pageable, total);
}
/**
* 사용자 ID 조회 UUID
*
* @param uuid
* @return
*/
@Override
public Optional<MemberEntity> findByUUID(UUID uuid) {
return Optional.ofNullable(
queryFactory.selectFrom(memberEntity).where(memberEntity.uuid.eq(uuid)).fetchOne());
}
}

View File

@@ -1,6 +1,6 @@
package com.kamco.cd.training.postgres.repository.menu;
import com.kamco.cd.training.postgres.entity.MenuEntity;
import org.springframework.data.jpa.repository.JpaRepository;
public interface MenuRepository extends JpaRepository<MenuEntity, String>, MenuRepositoryCustom {}
package com.kamco.cd.training.postgres.repository.menu;
import com.kamco.cd.training.postgres.entity.MenuEntity;
import org.springframework.data.jpa.repository.JpaRepository;
public interface MenuRepository extends JpaRepository<MenuEntity, String>, MenuRepositoryCustom {}

View File

@@ -1,9 +1,9 @@
package com.kamco.cd.training.postgres.repository.menu;
import com.kamco.cd.training.postgres.entity.MenuEntity;
import java.util.List;
public interface MenuRepositoryCustom {
List<MenuEntity> getFindAll();
}
package com.kamco.cd.training.postgres.repository.menu;
import com.kamco.cd.training.postgres.entity.MenuEntity;
import java.util.List;
public interface MenuRepositoryCustom {
List<MenuEntity> getFindAll();
}

View File

@@ -1,21 +1,21 @@
package com.kamco.cd.training.postgres.repository.menu;
import static com.kamco.cd.training.postgres.entity.QMenuEntity.menuEntity;
import com.kamco.cd.training.postgres.entity.MenuEntity;
import com.querydsl.jpa.impl.JPAQueryFactory;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;
@Repository
@RequiredArgsConstructor
public class MenuRepositoryImpl implements MenuRepositoryCustom {
private final JPAQueryFactory queryFactory;
@Override
public List<MenuEntity> getFindAll() {
return queryFactory.selectFrom(menuEntity).where(menuEntity.deleted.isFalse()).fetch();
}
}
package com.kamco.cd.training.postgres.repository.menu;
import static com.kamco.cd.training.postgres.entity.QMenuEntity.menuEntity;
import com.kamco.cd.training.postgres.entity.MenuEntity;
import com.querydsl.jpa.impl.JPAQueryFactory;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;
@Repository
@RequiredArgsConstructor
public class MenuRepositoryImpl implements MenuRepositoryCustom {
private final JPAQueryFactory queryFactory;
@Override
public List<MenuEntity> getFindAll() {
return queryFactory.selectFrom(menuEntity).where(menuEntity.deleted.isFalse()).fetch();
}
}

View File

@@ -1,9 +1,9 @@
package com.kamco.cd.training.postgres.repository.model;
import com.kamco.cd.training.postgres.entity.ModelDatasetMappEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface ModelDatasetMappRepository
extends JpaRepository<ModelDatasetMappEntity, ModelDatasetMappEntity.ModelDatasetMappId> {}
package com.kamco.cd.training.postgres.repository.model;
import com.kamco.cd.training.postgres.entity.ModelDatasetMappEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface ModelDatasetMappRepository
extends JpaRepository<ModelDatasetMappEntity, ModelDatasetMappEntity.ModelDatasetMappId> {}

View File

@@ -1,14 +1,14 @@
package com.kamco.cd.training.postgres.repository.model;
import com.kamco.cd.training.postgres.entity.ModelHyperParamEntity;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface ModelHyperParamRepository extends JpaRepository<ModelHyperParamEntity, String> {
List<ModelHyperParamEntity> findByDelYnOrderByCreatedDttmDesc(String delYn);
List<ModelHyperParamEntity> findByDelYnOrderByCreatedDttmAsc(String delYn);
}
package com.kamco.cd.training.postgres.repository.model;
import com.kamco.cd.training.postgres.entity.ModelHyperParamEntity;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface ModelHyperParamRepository extends JpaRepository<ModelHyperParamEntity, String> {
List<ModelHyperParamEntity> findByDelYnOrderByCreatedDttmDesc(String delYn);
List<ModelHyperParamEntity> findByDelYnOrderByCreatedDttmAsc(String delYn);
}

View File

@@ -1,17 +1,17 @@
package com.kamco.cd.training.postgres.repository.model;
import com.kamco.cd.training.postgres.entity.ModelTrainMasterEntity;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import org.springframework.data.jpa.repository.JpaRepository;
public interface ModelMngRepository
extends JpaRepository<ModelTrainMasterEntity, Long>, ModelMngRepositoryCustom {
List<ModelTrainMasterEntity> findByDelYnOrderByCreatedDttmDesc(Boolean delYn);
Optional<ModelTrainMasterEntity> findFirstByStatusCdAndDelYn(String statusCd, Boolean delYn);
Optional<ModelTrainMasterEntity> findByUuid(UUID uuid);
}
package com.kamco.cd.training.postgres.repository.model;
import com.kamco.cd.training.postgres.entity.ModelTrainMasterEntity;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import org.springframework.data.jpa.repository.JpaRepository;
public interface ModelMngRepository
extends JpaRepository<ModelTrainMasterEntity, Long>, ModelMngRepositoryCustom {
List<ModelTrainMasterEntity> findByDelYnOrderByCreatedDttmDesc(Boolean delYn);
Optional<ModelTrainMasterEntity> findFirstByStatusCdAndDelYn(String statusCd, Boolean delYn);
Optional<ModelTrainMasterEntity> findByUuid(UUID uuid);
}

View File

@@ -1,16 +1,16 @@
package com.kamco.cd.training.postgres.repository.model;
import com.kamco.cd.training.model.dto.ModelMngDto;
import com.kamco.cd.training.postgres.entity.ModelTrainMasterEntity;
import org.springframework.data.domain.Page;
public interface ModelMngRepositoryCustom {
/**
* 모델 목록 조회
*
* @param searchReq
* @return
*/
Page<ModelTrainMasterEntity> findByModels(ModelMngDto.SearchReq searchReq);
}
package com.kamco.cd.training.postgres.repository.model;
import com.kamco.cd.training.model.dto.ModelMngDto;
import com.kamco.cd.training.postgres.entity.ModelTrainMasterEntity;
import org.springframework.data.domain.Page;
public interface ModelMngRepositoryCustom {
/**
* 모델 목록 조회
*
* @param searchReq
* @return
*/
Page<ModelTrainMasterEntity> findByModels(ModelMngDto.SearchReq searchReq);
}

View File

@@ -1,61 +1,61 @@
package com.kamco.cd.training.postgres.repository.model;
import com.kamco.cd.training.model.dto.ModelMngDto;
import com.kamco.cd.training.postgres.entity.ModelTrainMasterEntity;
import com.kamco.cd.training.postgres.entity.QModelTrainMasterEntity;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.jpa.impl.JPAQueryFactory;
import java.util.List;
import java.util.Optional;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Repository;
@Repository
@RequiredArgsConstructor
public class ModelMngRepositoryImpl implements ModelMngRepositoryCustom {
private final JPAQueryFactory queryFactory;
private final QModelTrainMasterEntity modelMng = QModelTrainMasterEntity.modelTrainMasterEntity;
/**
* 모델 목록 조회
*
* @param searchReq
* @return
*/
@Override
public Page<ModelTrainMasterEntity> findByModels(ModelMngDto.SearchReq searchReq) {
Pageable pageable = searchReq.toPageable();
BooleanBuilder builder = new BooleanBuilder();
if (StringUtils.isNotBlank(searchReq.getStatus())) {
builder.and(modelMng.statusCd.eq(searchReq.getStatus()));
}
// Entity 직접 조회 (Projections 사용 지양)
List<ModelTrainMasterEntity> content =
queryFactory
.selectFrom(modelMng)
.where(builder.and(modelMng.delYn.isFalse()))
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.orderBy(modelMng.createdDttm.desc())
.fetch();
// Count 쿼리 별도 실행 (null safe handling)
long total =
Optional.ofNullable(
queryFactory
.select(modelMng.count())
.from(modelMng)
.where(builder.and(modelMng.delYn.isFalse()))
.fetchOne())
.orElse(0L);
return new PageImpl<>(content, pageable, total);
}
}
package com.kamco.cd.training.postgres.repository.model;
import com.kamco.cd.training.model.dto.ModelMngDto;
import com.kamco.cd.training.postgres.entity.ModelTrainMasterEntity;
import com.kamco.cd.training.postgres.entity.QModelTrainMasterEntity;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.jpa.impl.JPAQueryFactory;
import java.util.List;
import java.util.Optional;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Repository;
@Repository
@RequiredArgsConstructor
public class ModelMngRepositoryImpl implements ModelMngRepositoryCustom {
private final JPAQueryFactory queryFactory;
private final QModelTrainMasterEntity modelMng = QModelTrainMasterEntity.modelTrainMasterEntity;
/**
* 모델 목록 조회
*
* @param searchReq
* @return
*/
@Override
public Page<ModelTrainMasterEntity> findByModels(ModelMngDto.SearchReq searchReq) {
Pageable pageable = searchReq.toPageable();
BooleanBuilder builder = new BooleanBuilder();
if (StringUtils.isNotBlank(searchReq.getStatus())) {
builder.and(modelMng.statusCd.eq(searchReq.getStatus()));
}
// Entity 직접 조회 (Projections 사용 지양)
List<ModelTrainMasterEntity> content =
queryFactory
.selectFrom(modelMng)
.where(builder.and(modelMng.delYn.isFalse()))
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.orderBy(modelMng.createdDttm.desc())
.fetch();
// Count 쿼리 별도 실행 (null safe handling)
long total =
Optional.ofNullable(
queryFactory
.select(modelMng.count())
.from(modelMng)
.where(builder.and(modelMng.delYn.isFalse()))
.fetchOne())
.orElse(0L);
return new PageImpl<>(content, pageable, total);
}
}

View File

@@ -1,7 +1,7 @@
package com.kamco.cd.training.postgres.repository.upload;
import com.kamco.cd.training.postgres.entity.UploadSessionEntity;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UploadSessionRepository
extends JpaRepository<UploadSessionEntity, String>, UploadSessionRepositoryCustom {}
package com.kamco.cd.training.postgres.repository.upload;
import com.kamco.cd.training.postgres.entity.UploadSessionEntity;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UploadSessionRepository
extends JpaRepository<UploadSessionEntity, String>, UploadSessionRepositoryCustom {}

View File

@@ -1,22 +1,14 @@
package com.kamco.cd.training.postgres.repository.upload;
import com.kamco.cd.training.upload.dto.UploadDto;
import jakarta.validation.Valid;
import java.util.List;
import java.util.Optional;
import org.springframework.data.domain.Page;
public interface UploadSessionRepositoryCustom {
void insertUploadSession(UploadDto.UploadAddReq addReq);
UploadDto.uploadDto findByDatasetUid(Long datasetId, String uploadDivi);
UploadDto.uploadDto findByUuid(String uuid);
void updateUploadSessionStatus(UploadDto.UploadAddReq addReq);
}
package com.kamco.cd.training.postgres.repository.upload;
import com.kamco.cd.training.upload.dto.UploadDto;
public interface UploadSessionRepositoryCustom {
void insertUploadSession(UploadDto.UploadAddReq addReq);
UploadDto.uploadDto findByDatasetUid(Long datasetId, String uploadDivi);
UploadDto.uploadDto findByUuid(String uuid);
void updateUploadSessionStatus(UploadDto.UploadAddReq addReq);
}

View File

@@ -1,156 +1,132 @@
package com.kamco.cd.training.postgres.repository.upload;
import static com.kamco.cd.training.postgres.entity.QUploadSessionEntity.uploadSessionEntity;
import com.kamco.cd.training.postgres.entity.UploadSessionEntity;
import com.kamco.cd.training.upload.dto.UploadDto;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.Projections;
import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.core.types.dsl.CaseBuilder;
import com.querydsl.core.types.dsl.Expressions;
import com.querydsl.core.types.dsl.NumberExpression;
import com.querydsl.core.types.dsl.StringExpression;
import com.querydsl.jpa.impl.JPAQueryFactory;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import jakarta.validation.Valid;
import java.time.ZonedDateTime;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.UUID;
import org.hibernate.query.Query;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.support.QuerydslRepositorySupport;
public class UploadSessionRepositoryImpl extends QuerydslRepositorySupport
implements UploadSessionRepositoryCustom {
private final JPAQueryFactory queryFactory;
private final StringExpression NULL_STRING = Expressions.stringTemplate("cast(null as text)");
@PersistenceContext private EntityManager em;
public UploadSessionRepositoryImpl(JPAQueryFactory queryFactory) {
super(UploadSessionEntity.class);
this.queryFactory = queryFactory;
}
@Override
public void insertUploadSession(UploadDto.UploadAddReq addReq) {
long execCnt =
queryFactory
.insert(uploadSessionEntity)
.columns(
uploadSessionEntity.uploadId,
uploadSessionEntity.datasetId,
uploadSessionEntity.fileName,
uploadSessionEntity.fileSize,
uploadSessionEntity.finalPath,
uploadSessionEntity.status,
uploadSessionEntity.tempPath,
uploadSessionEntity.chunkIndex,
uploadSessionEntity.chunkTotalIndex,
uploadSessionEntity.uploadDivi,
uploadSessionEntity.fileHash,
uploadSessionEntity.uuid
)
.values(
addReq.getUploadId(),
addReq.getDatasetId(),
addReq.getFileName(),
addReq.getFileSize(),
addReq.getFinalPath(),
addReq.getStatus(),
addReq.getTempPath(),
addReq.getChunkIndex(),
addReq.getChunkTotalIndex(),
addReq.getUploadDivi(),
addReq.getFileHash(),
addReq.getUuid()
)
.execute();
}
@Override
public UploadDto.uploadDto findByDatasetUid(Long datasetId, String uploadDivi) {
UploadDto.uploadDto foundContent =
queryFactory
.select(
Projections.constructor(
UploadDto.uploadDto.class,
uploadSessionEntity.uploadId,
uploadSessionEntity.datasetId,
uploadSessionEntity.fileName,
uploadSessionEntity.fileSize,
uploadSessionEntity.finalPath,
uploadSessionEntity.uploadDivi,
uploadSessionEntity.status,
uploadSessionEntity.tempPath,
uploadSessionEntity.chunkIndex,
uploadSessionEntity.chunkTotalIndex,
uploadSessionEntity.fileHash,
uploadSessionEntity.uuid
))
.from(uploadSessionEntity)
.where(uploadSessionEntity.datasetId.eq(datasetId)
.and(uploadSessionEntity.uploadDivi.eq(uploadDivi)))
.limit(1)
.fetchOne();
return foundContent;
}
@Override
public UploadDto.uploadDto findByUuid(String uuid) {
UploadDto.uploadDto foundContent =
queryFactory
.select(
Projections.constructor(
UploadDto.uploadDto.class,
uploadSessionEntity.uploadId,
uploadSessionEntity.datasetId,
uploadSessionEntity.fileName,
uploadSessionEntity.fileSize,
uploadSessionEntity.finalPath,
uploadSessionEntity.uploadDivi,
uploadSessionEntity.status,
uploadSessionEntity.tempPath,
uploadSessionEntity.chunkIndex,
uploadSessionEntity.chunkTotalIndex,
uploadSessionEntity.fileHash,
uploadSessionEntity.uuid
))
.from(uploadSessionEntity)
.where(uploadSessionEntity.uuid.eq(UUID.fromString(uuid)))
.limit(1)
.fetchOne();
return foundContent;
}
public void updateUploadSessionStatus(UploadDto.UploadAddReq addReq){
long fileCount =
queryFactory
.update(uploadSessionEntity)
.set(uploadSessionEntity.chunkIndex, addReq.getChunkIndex())
.set(uploadSessionEntity.status, addReq.getStatus())
.where(uploadSessionEntity.uploadId.eq(addReq.getUploadId()))
.execute();
}
}
package com.kamco.cd.training.postgres.repository.upload;
import static com.kamco.cd.training.postgres.entity.QUploadSessionEntity.uploadSessionEntity;
import com.kamco.cd.training.postgres.entity.UploadSessionEntity;
import com.kamco.cd.training.upload.dto.UploadDto;
import com.querydsl.core.types.Projections;
import com.querydsl.core.types.dsl.Expressions;
import com.querydsl.core.types.dsl.StringExpression;
import com.querydsl.jpa.impl.JPAQueryFactory;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import java.util.UUID;
import org.springframework.data.jpa.repository.support.QuerydslRepositorySupport;
public class UploadSessionRepositoryImpl extends QuerydslRepositorySupport
implements UploadSessionRepositoryCustom {
private final JPAQueryFactory queryFactory;
private final StringExpression NULL_STRING = Expressions.stringTemplate("cast(null as text)");
@PersistenceContext private EntityManager em;
public UploadSessionRepositoryImpl(JPAQueryFactory queryFactory) {
super(UploadSessionEntity.class);
this.queryFactory = queryFactory;
}
@Override
public void insertUploadSession(UploadDto.UploadAddReq addReq) {
long execCnt =
queryFactory
.insert(uploadSessionEntity)
.columns(
uploadSessionEntity.uploadId,
uploadSessionEntity.datasetId,
uploadSessionEntity.fileName,
uploadSessionEntity.fileSize,
uploadSessionEntity.finalPath,
uploadSessionEntity.status,
uploadSessionEntity.tempPath,
uploadSessionEntity.chunkIndex,
uploadSessionEntity.chunkTotalIndex,
uploadSessionEntity.uploadDivi,
uploadSessionEntity.fileHash,
uploadSessionEntity.uuid)
.values(
addReq.getUploadId(),
addReq.getDatasetId(),
addReq.getFileName(),
addReq.getFileSize(),
addReq.getFinalPath(),
addReq.getStatus(),
addReq.getTempPath(),
addReq.getChunkIndex(),
addReq.getChunkTotalIndex(),
addReq.getUploadDivi(),
addReq.getFileHash(),
addReq.getUuid())
.execute();
}
@Override
public UploadDto.uploadDto findByDatasetUid(Long datasetId, String uploadDivi) {
UploadDto.uploadDto foundContent =
queryFactory
.select(
Projections.constructor(
UploadDto.uploadDto.class,
uploadSessionEntity.uploadId,
uploadSessionEntity.datasetId,
uploadSessionEntity.fileName,
uploadSessionEntity.fileSize,
uploadSessionEntity.finalPath,
uploadSessionEntity.uploadDivi,
uploadSessionEntity.status,
uploadSessionEntity.tempPath,
uploadSessionEntity.chunkIndex,
uploadSessionEntity.chunkTotalIndex,
uploadSessionEntity.fileHash,
uploadSessionEntity.uuid))
.from(uploadSessionEntity)
.where(
uploadSessionEntity
.datasetId
.eq(datasetId)
.and(uploadSessionEntity.uploadDivi.eq(uploadDivi)))
.limit(1)
.fetchOne();
return foundContent;
}
@Override
public UploadDto.uploadDto findByUuid(String uuid) {
UploadDto.uploadDto foundContent =
queryFactory
.select(
Projections.constructor(
UploadDto.uploadDto.class,
uploadSessionEntity.uploadId,
uploadSessionEntity.datasetId,
uploadSessionEntity.fileName,
uploadSessionEntity.fileSize,
uploadSessionEntity.finalPath,
uploadSessionEntity.uploadDivi,
uploadSessionEntity.status,
uploadSessionEntity.tempPath,
uploadSessionEntity.chunkIndex,
uploadSessionEntity.chunkTotalIndex,
uploadSessionEntity.fileHash,
uploadSessionEntity.uuid))
.from(uploadSessionEntity)
.where(uploadSessionEntity.uuid.eq(UUID.fromString(uuid)))
.limit(1)
.fetchOne();
return foundContent;
}
public void updateUploadSessionStatus(UploadDto.UploadAddReq addReq) {
long fileCount =
queryFactory
.update(uploadSessionEntity)
.set(uploadSessionEntity.chunkIndex, addReq.getChunkIndex())
.set(uploadSessionEntity.status, addReq.getStatus())
.where(uploadSessionEntity.uploadId.eq(addReq.getUploadId()))
.execute();
}
}