티스토리 뷰

package study.datajpa.entity;

import jakarta.persistence.Entity;
import jakarta.persistence.Id;

@Entity
public class Item {

    @Id
    private String id;

    protected Item() {
    }

    public Item(String a) {
    }


}
package study.datajpa.entity;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import study.datajpa.repository.ItemRepository;

import static org.junit.jupiter.api.Assertions.*;

@SpringBootTest
class ItemTest {

    @Autowired
    ItemRepository itemRepository;

    @Test
    public void newTest(){
        Item item = new Item("A");
        itemRepository.save(item); //이렇게 GeneratedValue가 아닌 id를 문자열로 주는 경우에는 persist가 아닌 merge가 동작해 버린다.
        /*
        @Transactional
        @Override
        public <S extends T> S save(S entity) {

            Assert.notNull(entity, "Entity must not be null");

            if (entityInformation.isNew(entity)) { //Long일 경우 null, long이면 0을 기준으로 판단..문자열이면 무조건 false가 나온다.
                entityManager.persist(entity);
                return entity;
            } else {
                return entityManager.merge(entity);
            }
        }
        */
    }

}

 

- JPA Repository는 Long 또는 0 외에는 이미 있던 엔티티라 생각하고 merge를 사용한다.

- merge는 셀렉트 문을 날리며 찾고 그걸 update하는데 select했을 떄에 없으면 인서트를 한다. 자원낭비가 발생한다.

 

 

해결

package study.datajpa.entity;

import jakarta.persistence.Entity;
import jakarta.persistence.EntityListeners;
import jakarta.persistence.Id;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.domain.Persistable;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import java.time.LocalDateTime;

@Entity
@EntityListeners(AuditingEntityListener.class)
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Item implements Persistable<String> {

    @Id
    private String id;

    @CreatedDate
    private LocalDateTime createdDate;
    public Item(String a) {
    }

    @Override
    public String getId() {
        return null;
    }

    @Override
    public boolean isNew() {
        return createdDate==null;
    }
}

 

- impl 받은 Persistable<id타입> 을 넣어주면 isNew를 오버라이딩 받을 수 있다.

- 보통은 createdDate로 그 값을 확인한다.

- 그럼 JPARepository에서도 isNew를 확인하여 새로운 애인지 확인한다.

 

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/11   »
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
글 보관함