250x250
Notice
Recent Posts
Recent Comments
Link
반응형
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- JPA
- List
- CSS
- GC로그수집
- BFS
- spring boot
- deque
- priority_queue
- date
- Properties
- 리소스모니터링
- dfs
- math
- map
- set
- 힙덤프
- html
- Calendar
- 스프링부트
- 큐
- javascript
- 스택
- scanner
- string
- sql
- Union-find
- NIO
- union_find
- alter
- Java
Archives
- Today
- Total
매일 조금씩
[JPA] 복합키일 때 셀프 조인 구현하기 - 부모(parent)/자식(children), @OneToMany, @ManyToOne, @JoinColumn, @JoinColumns 본문
공부/JPA
[JPA] 복합키일 때 셀프 조인 구현하기 - 부모(parent)/자식(children), @OneToMany, @ManyToOne, @JoinColumn, @JoinColumns
mezo 2022. 4. 22. 21:45728x90
반응형
파일과 폴더의 정보가 모두 'document'라는 테이블에 함께 저장된다고 하자.
이때, 폴더는 파일의 부모가 되므로 한테이블내에서 부모(parent)와 자식(children)이 존재한다.
PK는 'log_file_id' 와 'version' 이다.
이경우
이를 셀프조인을 사용하지 않고 폴더 안의 파일/폴더 리스트를 가져오려면..
1. 쿼리로 직접 셀프조인을 구현하여 리스트를 받아온다.
2. 'file_parent_id' 컬럼 값이 폴더의 'log_file_id' 값인 것을 찾아 java의 Object인 List<>에 담는다.
하지만 이는 JPA에서 손쉽게 해결할수 있다.
다음 코드를 보자.
@Entity
@Data
@NoArgsConstructor
@Table(name="document")
@IdClass(FilePK.class)
public class FileEntity {
@Id
@Column(name = "log_file_id")
private String logicalId;
@Id
@Column(name = "version")
private Integer version;
@Column(name = "file_parent_id")
private String parentId;
// 이하컬럼 생략 ..
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumns({
@JoinColumn(name = "file_parent_id", referencedColumnName = "log_file_id", insertable = false, updatable = false),
@JoinColumn(name = "version", referencedColumnName = "version", insertable = false, updatable = false)
})
private FileEntity parent;
@OneToMany(mappedBy = "parent", fetch = FetchType.LAZY)
private List<FileEntity> children = new ArrayList<>();
}
위처럼 @ManyToOne, @JoinColumns, @JoinColumn, @OneToMany 를 사용하여 조인하면된다.
다음은 서비스 코드이다.
@Service
@RequiredArgsConstructor
@Slf4j
public class FileServiceImpl implements FileService {
private final FileRepository fileRepository;
private final ModelMapper modelMapper = new ModelMapper();
@Override
@Transactional
public void deleteFilesByIsHardDelete(List<DeleteFileRequestDto> deleteFileRequestDtoList, boolean isHardDelete)
throws IOException {
if(isHardDelete){
deletePhysicalFileByNumberOfLogicalFiles(deleteFileRequestDtoList);
} else{
deleteFileInTrashBin(deleteFileRequestDtoList);
}
}
private void deleteFileInTrashBin(List<DeleteFileRequestDto> deleteFileRequestDtoList) {
for(DeleteFileRequestDto updateDelYNItem : deleteFileRequestDtoList){
FileEntity fileEntity = fileRepository.findByLogicalId(updateDelYNItem.getLogicalId());
if(updateDelYNItem.getIsFolder().equalsIgnoreCase("Y")){
for(FileEntity children : fileEntity.getChildren()){
children.setSoftDeleteForChildren(userId, children.getChannel());
fileRepository.save(children);
}
fileRepository.deleteByLogicalId(fileEntity.getLogicalId());
}else {
fileEntity.setSoftDelete(userId);
fileRepository.save(fileEntity);
}
}
}
private void deletePhysicalFileByNumberOfLogicalFiles(List<DeleteFileRequestDto> deleteFileRequestDtoList)
throws IOException {
for(DeleteFileRequestDto deleteItem : deleteFileRequestDtoList){
String physicalFileId = fileRepository.findByLogicalId(deleteItem.getLogicalId()).getPhysicalId();
if (deleteItem.getIsFolder().equalsIgnoreCase("N")){
fileRepository.deleteByLogicalId(deleteItem.getLogicalId());
deleteThumbnailPhoto(deleteItem.getLogicalId());
int numOfRemainingFiles = fileRepository.findByPhysicalId(physicalFileId);
if(numOfRemainingFiles == 0){
Files.deleteIfExists(Paths.get(FILE_ROOT_PATH, domainKey, physicalFileId));
}
}
}
}
}
위처럼 @Transactional 을 써줘야 fetch관련 에러가 발생하지않는다.
또한 getChildren()과 같이 쉽게 관련 리스트를 가져올수있다.
728x90
반응형
'공부 > JPA' 카테고리의 다른 글
org.hibernate.LazyInitializationException 오류 해결 (FetchType.LAZY) (0) | 2022.04.22 |
---|