본문 바로가기

Java/JPA

JPA에서 entity가 update가 아닌 insert가 되는 경우

결론:Entity의 colmun이 primary key이기 때문에 Entity의 colmun이 기존에 저장된 값과 다르면 새로운 행으로 인식되어 insert가 되는 것이다

 -- 내용 --
위와 같은 entity가 있다 치고

ExampleEntity exampleEntity = exampleRepository.findFirstByOrderByColumnAsc();

if (exampleEntity == null) {
    exampleEntity = new ExampleEntity();
}

exampleEntity.setColmun(BigInteger.valueOf(12345));
exampleRepository.save(exampleEntity);

아래 같은 로직이 있다 치자

entity가 null이 라면 new Entity가 생성되고 insert 될 것이고

entity가 null이 아니라면 해당 entity의 칼럼이 새롭게 set 돼서 update 될 것이다

그런데 entity가 null이 아님에도 새로운 row가 계속해서 추가되는 현상이 있었다.

한참 살펴봐도 로직은 문제가 없었고 entity를 찾아봤다.

 

문제의 entity를 보자

@Entity(name = "Example")
@Table(name = "tb_example")
public class ExampleEntity {
    @Id
    private BigInteger column;
    
    // ...
}

column이 id(primary key)로 잡혀있다

Entity의 colmun이 primary key이기 때문에 Entity의 colmun이 기존에 저장된 값과 다르면 새로운 행으로 인식되어 insert가 되는 것이다

이에 대한 해결로는 column을 primary key가 아니게 바꾸는 것이다.

row가 1개로 고정되는 테이블이기 때문에 column을 추가하기 싫었지만 그냥 추가했다.

 

아래 같이 엔티티를 수정하면 정상적으로 update가 된다

@Entity(name = "Example")
@Table(name = "tb_example")
public class ExampleEntity {
    @Id
    pricate int seq;
    
    private BigInteger column;
    
    // ...
}

 

원인을 몰라 굉장히 화가 났다

 

++ 추가
Column에 primary key만 제거하면 안될까 생각해서 단순하게 아래 같이 작성해봤지만 JPA 엔티티는 반드시 primary key를 가져야한다고 한다.
primary key가 없는 테이블을 사용하고 싶다면 @Embeddable 어노테이션을 사용해서 임베디드 타입으로 만들면 가능하지만 임베디드 타입은 엔티티가 아니기 때문에 JPA의 기능을 제한적으로 사용할 수 있다. 때문에 가능하면 primary key를 가진 엔티티를 사용하는 것이 좋다. ( = 결론은 그냥 primary key 박아놔라)

@Entity(name = "Example")
@Table(name = "tb_example")
public class ExampleEntity {
    private BigInteger column;
    
    // ...
}