이노베이션 캠프

[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