인프런 커뮤니티 질문&답변

김신배님의 프로필 이미지
김신배

작성한 질문수

스프링 데이터 JPA

데이터 입력/수정시 entity 의 필드 갱신

해결된 질문

작성

·

358

0

좋은 강의 감사합니다. 😃

jap 를 이용한 기능구현 중 궁금한 사항이 있어 문의 드립니다.

 

저장작업 직후 DB 에서 생성된 timestamp 정보를 entity filed 와 연동시키는 방법이 없을까요?

webApp 의 시간을 사용할 수 없는 상황입니다. 😭

 

감사합니다.

 

* 목표

EntityManager 의 clear 를 사용하지 않고

입력/수정작업 후 DB 에서 생성되는 timestamp 값을 entity 에 담아 API 응답

 

* 상태

1. DB 의 timestamp 기능을 이용하여 데이터의 입력/수정시간을 자동생성 하도록 팀내 합의

2. entity 에 입력시간, 수정시간 필드가 존재하나 query 에서 insert, update 시 사용하지 않도록 처리

   (insertable = false, updatable = false)

3. 신규 데이터의 입력/수정 작업 후 DB 에는 timestamp 값이 생성되나

   save or saveAndFlush 작업 후 리턴받는 entity 의 값은 null 인 생태

4. 컨트롤러에서 서비스의 저장작업 후 다시 조회를 하더라도  cache 값이 조회됨

5. EntityManager 를 이용하여 clear 후 조회 시 DB 값을 정상조회

 

PostEntity.java

@Getter @Setter
@Entity @Table(name = "post")
@EntityListeners(AuditingEntityListener.class)
public class PostEntity implements Serializable {
	
	private static final long serialVersionUID = -6794700285084640362L;

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Long id;
	
	private String title;
	
	//DB timestamp
	@Column(insertable = false, updatable = false)
	private LocalDateTime inDt;
	
	//DB timestamp
	@Column(insertable = false, updatable = false)
	private LocalDateTime upDt;	
}

PostController.java

@RestController
@RequestMapping("/api/v1")
@Api(value = "API Manage")
public class PostController {
	
	@Autowired
	PostService postService;
	
	@ApiOperation(value = "Create Post")
	@PostMapping("/post")
	public ResponseEntity<PostEntity> postCreate() throws Exception {
		PostEntity newPost = postService.postCreate();
		long createdId = newPost.getId();
		System.out.println("np : in : " + newPost.getInDt());	//null
		System.out.println("np : up : " + newPost.getUpDt());	//null
		
		PostEntity rePost = postService.postGet(createdId);
		System.out.println("rp : in : " + rePost.getInDt());	//null
		System.out.println("rp : up : " + rePost.getUpDt());	//null
		
		return new ResponseEntity<PostEntity>(newPost, HttpStatus.OK);
	}
}

PostService.java

@Service
public class PostService {
	
	@Autowired
	private PostRepository postRepo;
	
	@Transactional
	public PostEntity postCreate() {
		PostEntity post = new PostEntity();
		post.setTitle("new post create");
		PostEntity newPost = postRepo.save(post);
		return newPost;
	}
	
	@Transactional(readOnly = true)
	public PostEntity postGet(long postId) throws Exception {
		PostEntity searchPost = postRepo.findById(postId)
				.orElseThrow(
						() -> new Exception("resource not found")
				);
		
		return searchPost;
	}
}

답변 2

0

김신배님의 프로필 이미지
김신배
질문자

도커 기반으로 webApp 를 다중관리 할 때 도커마다 시간이 동일하지 않을 수 있다는 우려에서

timestamp 를 DB 에서 처리하는것으로 이야기가 되었었습니다.

(개발자 모두 도커를 처음 사용하는 상황)

 

http://blog.naver.com/PostView.nhn?blogId=wideeyed&logNo=221387159464

위 블로그의 내용대로 호스트의 시간을 각 도커에 적용하여 통일하는 방향으로

다시 이야기를 나눠봐야 할것 같습니다.

 

감사합니다. 😊

0

백기선님의 프로필 이미지
백기선
지식공유자

저라면 스프링 데이터 JPA가 제공하는 Audit 기능을 사용해서 (아마 수업에서 다뤘을 겁니다.) 수정이나 입력시 시간 정보를 생성할거 같네요. 그럼 엔티티에서 사용할 수 있을테니까요.

왜 애플리케이션 서버의 시간을 쓸 수 없는지는 잘 모르겠네요. 애플리케이션 서버 시간대 무시하고 UTC 기준으로 저장을 하고 꺼낼 때 Locale에 맞게 변환해서 쓰면 되지 않을까 싶은데 어렵네요.

그리고 비효율적이네요. 하이버네이트 1차 캐시를 쓰지 못하고 매번 저장한 다음엔 새로운 트랜잭션에서 엔티티를 읽어와야 하다니.. 딱히 좋은 방법이 떠오르지 않습니다.

김신배님의 프로필 이미지
김신배

작성한 질문수

질문하기