2017-01-30 10 views
2

문제점을 해결하는 가장 좋은 방법이 무엇인지 모르는 이상한 문제가 있습니다."org.springframework.dao.InvalidDataAccessApiUsageException : Spring 통합 테스트를 실행할 때 동일한 여러 표현 표현"

org.springframework.dao.InvalidDataAccessApiUsageException : 같은 여러 표현 나는 내가 Spring JUnit 환경에서 실행할 때, 나는 다음과 같은 예외를 얻을, 데이터베이스에 잘 지속 얻을 일부 JPA 엔티티 클래스를 썼다 엔티티 [com..xyzAddress # 0]이 으로 병합되었습니다. 분리됨 : [com..x.y.z.Address @ 48d9d51f]; 관리 대상 : [com..x.y.z.Address @ 4a5e389b]; 중첩 예외는 입니다. java.lang.IllegalStateException : 동일한 엔터티 [com..x.y.z.Address # 0]의 여러 표현이 병합 중입니다. 분리됨 : [com..x.y.z.Address @ 48d9d51f]; 관리 : [com..xyzAddress @ 4a5e389b]

내 엔티티 클래스는 다음과 유사한 : 정보의

class User { 

    @Id 
    @SequenceGenerator(name = "USER_ID_GENERATOR", sequenceName = "USER_SEQ") 
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "USER_ID_GENERATOR") 
    private String id; 

    @OneToMany(mappedBy = "user", fetch = FetchType.EAGER, cascade = CascadeType.ALL) 
    private Set<Address> addresses = new HashSet<>(); 
} 

class Address{ 
    @Id 
    private long addressId; 

    private String addressLine; 

    @ManyToOne 
    @JoinColumn(name="user_id") 
    private User user; 
} 

한 조각, 나는 스프링 JPA의를 사용하고 있습니다 추가 할 CrudRepository 저장하지 않습니다.

내 테스트의 간단한 연주는 다음과 같습니다

@RunWith(SpringJUnit4ClassRunner.class) 
@SpringApplicationConfiguration(classes = {MyApplication.class}) 
@WebIntegrationTest({ "server.port=12345", "server.url=http://127.0.0.1:12345" }) 
@DirtiesContext 
public class MyIntegrationTest { 

private UserRepository userRepository 

@Test 
public void testSave(){ 
    User user = new User(1, "James"); 
    Address address1 = new Address("1234 xyz street"); 
    user.addAddress(address1); 

    userRepository.save(user); 

    User user = userRepository.findById(1); 
    Address address2 = new Address("111 abc street"); 
    user.addAddress(address2); 
    userRepository.save(user) // this is where the exception happens while running the test 
} 
} 

내 테스트 및 실제 실행 환경 모두에서이 실행 벌금을 어떻게해야합니까? 감사합니다

+0

우리가 당신의 테스트를 보여줍니다 –

+0

특히 주소 인스턴스를 생성하고 데이터를 채우는 방법에 관심이 있습니다 –

+0

찾고있는 정보로 내 질문을 업데이트했습니다. – Seagull

답변

2

확인은, 내가 볼때 ..

주소 엔티티는 어떤 세대 전략없이 @Id이 있으므로 거기에 무엇이든, 기본 키 간주됩니다. 귀하는 사용자의 모든 작업을 계단식

해결하려면 다음을

@OneToMany(mappedBy = "user", fetch = FetchType.EAGER, cascade = CascadeType.ALL) 

그래서 난 당신이 사용자를 저장 두 번째 시간을 추측하고, 실제로 최초의 병합을 시도 ..

을 이제 두를 만들 id ..를 지정하지 않고 인스턴스를 처리합니다. 따라서 두 경우 모두 0이됩니다. 먼저 저장하면 EAGER 페칭 때문에 첫 번째 주소와 함께 사용자를 검색하고 다른 주소를 만들고 ID는 다시 0이됩니다.

이제는 동일한 ID를 가진 두 개의 주소로 끝납니다. 하나는 영구 컨텍스트로 관리되고 다른 하나는 분리됩니다. 병합 중에 오류가 발생합니다.

나는 그것을 증명할 수는 없지만 주소에 대해 각각 12 (또는 다른 두 개의 다른 ID)으로 ID를 지정하면 그 오류를 다시 볼 수 없습니다.

+0

여기에 좋은 점이있어보십시오. 시도해 보겠습니다. – Seagull

+0

감사합니다!두 주소 인스턴스가 서로 다른 ID를 가지고 있는지 확인한 후에는 작동했습니다. 고마워요! – Seagull

+0

까다 롭습니다. 다행히 도울 수있어. –