2014-12-28 4 views
7

안녕하세요 저는 Sprig Data JPA을 처음 접했습니다. ID를 엔티티에 전달하더라도 스프링 데이터 jpa가 병합 대신 삽입됩니다.스프링 데이터 JPA 업데이트 대신 삽입

public Long getId(); 
public Boolean isNew(); 

그것은 자동으로 대신 지속의 병합합니다 : 본인은 또한 지속 인터페이스를 구현하고 두 가지 방법을 구현할 때 생각했다.

내가 좋아하는 엔티티 클래스라는 사용자가 :

@Entity 
@Table(name = "T_USER") 
public class User implements Serializable, Persistable<Long> { 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    @Column(name = "USER_ID") 
    private Long id; 

    @Column(name = "CREATION_TIME", nullable = false) 
    private Date creationTime; 

    @Column(name = "FIRST_NAME", nullable = false) 
    private String firstName; 

    @Column(name = "LAST_NAME", nullable = false) 
    private String lastName; 

    @Column(name = "MODIFICATION_TIME", nullable = false) 
    private Date modificationTime; 

을 내가 UserRepostory 확장 JpaReopistory라는 사용자 지정 저장소가 다른 클래스

@Entity 
@Table(name = "T_USER_ROLE") 
public class UserRole implements Serializable, Persistable<Long> { 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long roleId; 

    @Column(name = "ROLE_NAME") 
    private String userRole; 
} 

있습니다. 나는 Spring Data Jpa가 위의 두 가지 방법 중 하나를 사용하여 업데이트하거나 삽입한다는 것을 보여주기 때문에 병합을 위해 저장을 기다리고 있습니다.

@Repository 
public interface UserRepository extends JpaRepository<User, Long> { 
} 

나는 알아 내려고했지만 아무런 단서도 얻지 못했습니다. 어쩌면 당신 남자들이 도울 수 있습니다.

+0

지속성 인터페이스를 구현할 필요가 없습니다. 상속 된'save'를 사용하면 스프링 데이터가 그것을 처리 할 것입니다. –

답변

20

이 문제가 발생하여 Persistable을 구현하지 않으려 고 시도한 다음 Spring Data JPA 소스를 살펴 보았습니다. 필자는 예제 코드에서 이것을 반드시 볼 수는 없지만 내 엔티티에 @Version 필드가 있습니다. @Version 필드가있는 경우 Spring 데이터는 값을 테스트하여 엔티티가 새 것인지 아닌지를 결정합니다. @Version 필드가 프리미티브가 아니고 null 인 경우 엔티티는 새로운 것으로 간주됩니다.

내 표현에서 버전 필드를 설정하지 않았지만 지속 된 엔터티에서만 설정했기 때문에 이것은 내 테스트에서 오랫동안 나를 던졌습니다. 나는 또한 다른 도움이되는 Spring Data 문서 (...에서이 문서화되어 있음)를 보지 못했다.

희망을 누군가에게 도움이됩니다!

+0

네가 맞다.엔티티에 버전 필드가 있습니다. Spring Data JPA가 그 필드를 찾을 줄은 몰랐습니다. –

+0

나는 정확히 같은 문제를 가지고 있으며 @Version 주석이 아닙니다 ... – multiplayer1080

+0

이 답변을 주셔서 감사합니다. 같은 문제를 겪었습니다! – JamesG

2

기본적으로 스프링 데이터 JPA는 주어진 엔티티의 식별자 속성을 검사합니다. 식별자 속성이 null이면 엔티티는 새로운 것으로 간주되고 그렇지 않으면 새로운 것으로 간주됩니다. 당신이 EntityManeger이 entuty 업데이트됩니다 .merge()를 호출하고 .persist() 삽입됩니다와 스프링 JPA를 사용하는 경우는 Id-Property inspectionReference

을합니다.

@PersistenceContext 
private EntityManager em; 

@Override 
@Transactional 
public User save(User user) { 

    if (user.getId() == null) { 
     em.persist(user); 
     return user; 
    } else { 
     return em.merge(user); 
    } 
} 

Persistable 인터페이스를 구현할 필요가 없습니다.

+0

@njjnex 감사합니다. 그러나 JpaRepository 인터페이스를 사용하고 Service 클래스에서 save 메소드를 호출하면 엔티티가 새 것이거나 아닌지 내부적으로 스프링 데이터 JPA가 확인한다. 이런 식으로 엔티티가 Spring의 Persistable 인터페이스를 구현할 때, 그것은 두 가지 메소드를 대체합니다. 1. Boolean isNew() 및 2. Long getId(). 하지만 작동하지 않습니다. –

+2

내가 말했듯이 Spring Data Jpa에 들어갔고 이전에 자체 dao 레이어를 사용했습니다. 위와 같이 언급 한 방식으로 entityManager를 DAO 구현에 전달했습니다. 그 잘 작동하지만 내 질문은 스프링 데이터 Jpa 컨텍스트에서 작동하지 않는 이유입니다. –

관련 문제