๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

JPA

ํŒจ์ŠคํŠธ์บ ํผ์Šค ์ฑŒ๋ฆฐ์ง€ 4์ผ์ฐจ - EntityListener

๐Ÿ“Œ Entity Listener

์ด๋ฒคํŠธ์— ๋”ฐ๋ฅธ ์—”ํ‹ฐํ‹ฐ์˜ ์ „์ฒ˜๋ฆฌ, ํ›„์ฒ˜๋ฆฌ

 

JPA์—์„œ ์ œ๊ณต๋˜๋Š” 7๊ฐ€์ง€ ์ด๋ฒคํŠธ

  • ์ „์ฒ˜๋ฆฌ Listener
    • @PrePersist (persist ํ˜ธ์ถœ ์ „)
    • @PreUpdate (merge(update) ํ˜ธ์ถœ์ „ )
    • @PreRemove (delete ํ˜ธ์ถœ์ „)
  • ํ›„์ฒ˜๋ฆฌ Listener
    • @PostPersist
    • @PostUpdate
    • @PostRemove
    • @PostLoad select(์กฐํšŒ) ํ›„์— ํ˜ธ์ถœ

์—”ํ‹ฐํ‹ฐ์— ์ง์ ‘ ์ •์˜ํ•˜๋Š” ๋ฐฉ์‹

@PrePersist
public void prePersist() {
log.info("prePersist ํ˜ธ์ถœ");
}
@PostPersist  
public void postPersist() {  
log.info("postPersist ํ˜ธ์ถœ");  
}
@PostLoad  
public void postLoad() {  
log.info("postLoad ํ˜ธ์ถœ");  
}

Auditng

 

โœ”๏ธ ์•„๋ž˜ ๋ฉ”์„œ๋“œ๊ฐ€ ์ •์˜๋œ ์—”ํ‹ฐํ‹ฐ์— persist(์ €์žฅ) ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค๋ฉด persist ์ „์— ์•„๋ž˜ ๋ฉ”์„œ๋“œ๋ฅผ ๋จผ์ € ์ˆ˜ํ–‰ํ•œ๋‹ค.
Listener๋ฅผ ํ†ตํ•ด persist์‹œ ์ž๋™์œผ๋กœ ํ•„๋“œ ์ดˆ๊ธฐํ™” ๊ฐ€๋Šฅ

@PrePersist
public void prePersist() {
    this.createdAt = LocalDateTime.now();
    this.updatedAt = LocalDateTime.now();
}

 

โœ”๏ธ ์•„๋ž˜ ๋ฉ”์„œ๋“œ๊ฐ€ ์ •์˜๋œ ์—”ํ‹ฐํ‹ฐ์— update(์ˆ˜์ •) ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค๋ฉด update ์ „์— ์•„๋ž˜ ๋ฉ”์„œ๋“œ๋ฅผ ๋จผ์ € ์ˆ˜ํ–‰ํ•œ๋‹ค.
Listener๋ฅผ ํ†ตํ•ด ์ˆ˜์ •์‹œ๊ฐ„์„ ์ž๋™์œผ๋กœ ๊ฐฑ์‹  ๊ฐ€๋Šฅ

@PreUpdate
public void preUpdate() {
    this.upadtedAt = LocalDateTime.now();
}

EntityListener ํด๋ž˜์Šค ์ž‘์„ฑ

 

โœ”๏ธ EntityListener Class ์ž‘์„ฑ

public class MyEntityListener{
    ...
}

โœ”๏ธ Entity์— ์ž‘์„ฑํ•œ EntityListener Class๋ฅผ ๋“ฑ๋ก
@EntityListeners๋ฅผ ํ†ตํ•ด ์ •์˜ํ•œ ๋ฆฌ์Šค๋„ˆ ํด๋ž˜์Šค๋ฅผ ์—ฌ๋ ค ๊ฐœ ๋“ฑ๋ก ๊ฐ€๋Šฅ

@EntityListeners(value = MyEntityListener.class)
public class User{
    ...
}

๋ณ€๊ฒฝ์— ๋Œ€ํ•œ ํžˆ์Šคํ† ๋ฆฌ ๋งŒ๋“ค๊ธฐ

 

User ์—”ํ‹ฐํ‹ฐ์— ๋Œ€ํ•œ ํžˆ์Šคํ† ๋ฆฌ๋ฅผ ์œ ์ง€ํ•˜๊ณ ์ž ํ•จ

  • @PreUpdate๋ฅผ ์ด์šฉํ•ด์„œ ์—…๋ฐ์ดํŠธ ์ด์ „ ์—”ํ‹ฐํ‹ฐ์˜ ์ƒํƒœ๋ฅผ ๋ฐฑ์—…
  • User์™€ ๋™์ผํ•œ UserHistory ์—”ํ‹ฐํ‹ฐ ์ž‘์„ฑ
  • UserEntity์˜ Listener ํด๋ž˜์Šค ์ž‘์„ฑ

โœ”๏ธ ๋ฆฌ์Šค๋„ˆ ํด๋ž˜์Šค ์ž‘์„ฑ

public class UserListener{

    @PreUpdate
    public void preUpdate(Object o) {
        User user = (user) o;

        UserHistory userHistory = new UserHistory();
        userHistory.setName(user.getName());
        userHistory.setEmail(user.getEmail());
        userHistory.setAge(user.getAge());


        userHistory.save(userHistory);
    }
}

Listener ํด๋ž˜์Šค์—์„œ Bean์„ ์ฃผ์ž…๋ฐ›๋Š” ๋ฐฉ๋ฒ•

 

๋ฆฌ์Šคํ„ฐ ํด๋ž˜์Šค์—์„œ๋Š” ๋ณดํ†ต์˜ ๋ฐฉ๋ฒ• @Autowired, ์ƒ์„ฑ์ž ์ฃผ์ž… ๋“ฑ์œผ๋กœ ์ฃผ์ž…์ด ๋ถˆ๊ฐ€๋Šฅํ•จ.
(Listenerํด๋ž˜์Šค์—์„œ repository ๋“ฑ์„ ์‚ฌ์šฉํ•ด์•ผํ•˜๋Š” ๊ฒฝ์šฐ)

์ž‘์„ฑํ•œ BeanUtilsํด๋ž˜์Šค๋ฅผ ํ†ตํ•ด Bean์„ ์ง์ ‘ ์ฐ์–ด์„œ ๊ฐ€์ ธ์˜ด

  1. ApplicationContextAware๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ํด๋ž˜์Šค ์ž‘์„ฑ
  2. ApplicationContextAware์˜ ๊ตฌํ˜„ ๋ฉ”์„œ๋“œ์ธ setApplicationContext ๊ตฌํ˜„
  3. setApplicationContext์—์„œ ApplicationContext๋ฅผ ๋ฐ›์•„์˜ฌ ์ˆ˜ ์žˆ์Œ.
  4. ํด๋ž˜์Šค ํƒ€์ž…์œผ๋กœ ๋นˆ์„ ์กฐํšŒํ•  ์ˆ˜ ์žˆ๋Š” ๋ฉ”์„œ๋“œ ์ •์˜ (getBean)
@Component
public class BeanUtils implements ApplicationContextAware {
    private static ApplicationContext ac;

    // ApplicationContext ์ฃผ์ž…
    @Override
    public void setApplicationContext(ApplicationContext ac) {
        BeanUtils.ac = ac;
    }

    public static <T> T getBean(Class<T> clazz) {
        return ac.getBean(clazz);
    }
}

โœ”๏ธ UserRepository๋ฅผ ๊ฐ–๊ณ ์˜ค๊ณ  ์‹ถ๋‹ค๋ฉด ?

BeanUtils.getBean(UserRepository.class);

Spring์ด ์ œ๊ณตํ•˜๋Š” Listener
AuditingEntityListener

  • Mainํด๋ž˜์Šค์— @EnableJpaAuditing ์ถ”๊ฐ€
  • @EntityListeners = (value = {AuditingEntityListener.class,})
  • @CreatedDate, @LastModifiedDate ์‚ฌ์šฉ๊ฐ€๋Šฅ
  • @CreatedBy, @LadModifedBy ์‚ฌ์šฉ๊ฐ€๋Šฅ

๐Ÿ‘ ์ˆ˜๊ฐ•์ธ์ฆ

 

 

ํŒจ์ŠคํŠธ์บ ํผ์Šค [์ง์žฅ์ธ ์‹ค๋ฌด๊ต์œก]

ํ”„๋กœ๊ทธ๋ž˜๋ฐ, ์˜์ƒํŽธ์ง‘, UX/UI, ๋งˆ์ผ€ํŒ…, ๋ฐ์ดํ„ฐ ๋ถ„์„, ์—‘์…€๊ฐ•์˜, The RED, ๊ตญ๋น„์ง€์›, ๊ธฐ์—…๊ต์œก, ์„œ๋น„์Šค ์ œ๊ณต.

fastcampus.co.kr

๋ณธ ํฌ์ŠคํŒ…์€ ํŒจ์ŠคํŠธ์บ ํผ์Šค ํ™˜๊ธ‰ ์ฑŒ๋ฆฐ์ง€ ์ฐธ์—ฌ๋ฅผ ์œ„ํ•ด ์ž‘์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.