이노베이션 캠프
[TIL] 53일차
hjkim0502
2022. 9. 23. 03:09
미루던 til 한번에 몰아쓰기...
1. 지연 로딩 관련 에러
게시글 - 댓글
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.innovation.stockstock.entity.Post.comments, could not initialize proxy - no Session
- 양방향 1:N 연관관계인 상황에서 모두 지연로딩으로 설정하니 게시글을 통해 댓글을 조회할 때 (게시글 상세조회) 트랜잭션이 끝나고 나서 댓글 프록시 객체가 초기화 시도하여 댓글 정보를 불러오지 못하는 문제가 생김
- 게시글에서 즉시 로딩 전략을 사용해 바로 가져올 수도 있지만, 대부분의 경우 댓글 정보는 필요가 없어 서비스 단에서 댓글 정보도 다 필요했던 메소드에 @Transactional을 사용해 해결
게시글 - 사용자, 댓글 - 사용자
HttpMessageNotWritableException: Could not write JSON: failed to lazily initialize a collection of role
- 위 문제 해결 후 게시글 전체 조회할 때 작성자 객체가 지연 로딩되는데 실패하는 문제, 게시글 상세 조회할 때 조회되는 댓글들에 대해 또 작성자 객체가 지연 로딩 실패하여 이부분은 즉시로딩으로 해결했다
- 위 상황과 다르게, 게시글과 댓글에 대응되는 사용자는 한개밖에 없고, 사용자 객체에 필드도 별로 없기 때문에 즉시로딩해도 큰 무리 없겠다 싶었다
2. @GeneratedValue
- 연관관계 문제를 다 해결하고 객체들에 IDENTITY 전략을 사용해서 id를 만들어야겠다 했는데, 게시글에 댓글을 작성하니, 더이상 그 게시물을 상세조회 하지 못하는 에러 발생
- IDENTITY 전략은 원래는 DB에 객체가 저장되기 전까지는 id 값이 실제 세팅이 안되는데, 영속성 컨텍스트에서 관리하기 위해서는 pk가 필수적이라 예외적으로 em.persist 시점에 insert 쿼리가 날라가도록 세팅되어있다고 한다
- 그럼에도 무슨 이유인지 게시물 조회할 때 사용자 id 값을 불러올 수 없다는 에러가 떠서 그냥 디폴트인 AUTO 전략으로 유지하고 있다
3. Github Actions
- CD 작업할 때 gitignore한 파일을 처리하는 방법 중 간편한 방법을 찾아 성공했다
## create application.properties
- name: make application.properties
run:
mkdir ./src/main/resources |
touch ./src/main/resources/application.properties
shell: bash
- name: deliver application.properties
run: echo "${{ secrets.PROPERTIES }}" > ./src/main/resources/application.properties
shell: bash
- 빌드 전에 필요한 파일을 만들고, 깃헙 secret에 PROPERTIES라는 키 값에 파일에 저장한 내용을 넣어 이를 위처럼 secrets.PROPERTIES로 불러와 만든 파일에 붙여넣는다
- 이전에 다른 조는 git ignore한 여러 properties 파일을 ignore하지 않은 application.properties에서 불러와서 사용할 수 있게 하고 워크플로우에서 빌드전에 위와 비슷하게 각 파일들을 생성했다
4. toString() vs String.valueOf()
- 대상 객체가 null인 경우 toString은 NullPointException 발생, String.valueOf()는 "null" 반환
- 댓글, 게시글 dto에서 createdAt, modifiedAt 필드를 String으로 변환할 때 toString()은 NPE에러를 발생시켜 String.valueOf()로 처리했다
5. Websocket
- 실시간 데이터 교환에 유용한 기술
- 일반적인 HTTP는 요청 - 응답 싸이클의 반복(비연결, 무상태)
- 따라서 서버는 클라의 요청이 없다면 데이터를 줄 수 없기 때문에 실시간 데이터 교환에 매우 좋지 않다
- 폴링: 클라에서 지정된 시간(30초, 1분 등)마다 서버에 요청을 보내도록 해 데이터를 업데이트하는 방식
- SSE: HTTP 통신 기반으로, 클라가 커넥션을 열어주면 서버가 단방향으로 계속 데이터를 전송할 수 있다
- 활용 예) 주식 정보, 날씨 정보 등
- 모든 브라우저에서 지원하지는 않는다는 단점이 있음
- 채팅과 같은 양방향 실시간 데이터 통신이 필요한 경우 Websocket을 사용해볼 수 있다 (TCP 연결)
- 채팅에 참여하는 클라이언트들은 웹소켓 서버에 소켓 연결을 한 상태로 유지
- 화상채팅은 보통 WebRTC 사용
- SockJS: (간단히) 웹소켓 지원하지 않는 브라우저에도 사용할 수 있게 해줌
- STOMP: 메세지 전송을 더 효율적으로 하게 하기 위한 프로토콜(pub/sub)
- 스프링에선 WebSocketHandler 객체 구현 없이 어노테이션으로 간편하게 구현 가능
- 웹 소켓 서버가 여러개인 경우: 서버끼리 생성한 세션 정보가 공유 되어야 함
- 이때 외부 메세지 브로커를 사용하면 좋다 (단점: 비용 증가)
- 예) RabbitMQ
- 그렇지 않다면 각 사용자가 어떤 채널을 구독중이고, 어떤 서버에 접속중인지 어딘가에서 저장해야 한다
- https://brunch.co.kr/@springboot/695
- 이때 외부 메세지 브로커를 사용하면 좋다 (단점: 비용 증가)