[SPRING] 스프링 데이터 JPA 분리 엔터티
SPRING스프링 데이터 JPA 분리 엔터티
스프링 데이터 JPA를 사용하여 스프링 부트 애플리케이션으로 작업하여 사용자와 롤 간의 ManyToMany 관계를 설정하기 시작했습니다.
이 관계는 User 클래스에서 다음과 같이 정의됩니다.
@ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinTable(name="user_role", joinColumns = {@JoinColumn(name="user_id")}, inverseJoinColumns = {@JoinColumn(name="role_id")})
private Set<UserRole> roles;
다음을 사용하여 역할을 만듭니다.
@Transactional
private void generateSeedRoles() {
UserRole adminRole = new UserRole(RoleEnum.ADMIN.toString());
userRoleRepository.save(adminRole);
UserRole userRole = new UserRole(RoleEnum.USER.toString());
userRoleRepository.save(userRole);
}
나중에 사용자에게 역할 할당 실패 :
@Transactional
private void generateSeedUsers() {
UserRole adminRole = userRoleRepository.findUserRoleByRoleName("ADMIN");
User user = User.createUser("user1", "user1@user.com", "pass");
user.setRoles(new HashSet<UserRole>(Arrays.asList(adminRole)));
userRepository.save(user);
}
다음과 같은 예외가 발생합니다 (가독성을 위해 형식이 지정됨).
org.springframework.dao.InvalidDataAccessApiUsageException:
detached entity passed to persist: co.feeb.models.UserRole;
nested exception is org.hibernate.PersistentObjectException:
detached entity passed to persist: co.feeb.models.UserRole
그러나 관계가 만들어지기 전에 사용자가 저장되면 제대로 작동합니다.
@Transactional
private void generateSeedUsers() {
UserRole adminRole = userRoleRepository.findUserRoleByRoleName("ADMIN");
User user = User.createUser("user1", "user1@user.com", "pass");
//Save user
userRepository.save(user);
//Build relationship and update user
user.setRoles(new HashSet<UserRole>(Arrays.asList(adminRole)));
userRepository.save(user);
}
사용자를 두 번 저장 / 업데이트하는 것은 나에게 다소 불합리한 것처럼 보입니다. 사용자를 먼저 저장하지 않고 새 사용자에게받은 역할을 할당 할 수있는 방법이 있습니까?
해결법
-
==============================
1.엔티티를 저장할 때, Spring은 엔티티가 새로운 것인지를 내부적으로 검사하고 (정확한 메커니즘을 잊어 버림) 영속 (새 경우) 또는 병합 (존재하는 경우) 중 하나를 발행합니다.
엔티티를 저장할 때, Spring은 엔티티가 새로운 것인지를 내부적으로 검사하고 (정확한 메커니즘을 잊어 버림) 영속 (새 경우) 또는 병합 (존재하는 경우) 중 하나를 발행합니다.
사용자가 Cascade.ALL과 UserRole 관계를 정의 했으므로 User의 지속성 / 병합이 UserRole에도 캐스케이드됩니다.
Spring이 저장을 구현하는 방법과 위에 계단식으로 동작하는 방법을 고려할 때 다음과 같은 몇 가지 시나리오를 고려해야합니다.
사용자와의 관계에 추가 한 UserRole이 항상 존재 함을 보장 할 수 있으면 계단식 옵션에서 Cascade.Persist를 제거하면됩니다. 그렇지 않으면 위의 두 시나리오에서 사용자를 저장할 때 사용자 지정 저장소 및 entityManager를 통해 병합을 사용해야한다고 생각합니다.
이 상황에서 아마도 이해가되지 않는 Cascade.ALL의 사용에 관해서는 @ManyToMany 관계가 있기 때문에 User에서 UserRole까지 모두를 계단식으로 연결하면 원하지 않는 결과가 발생할 수 있습니다 (예 : Cascade.Remove는 매번 UserRole을 제거합니다 사용자가 삭제됨).
from https://stackoverflow.com/questions/31037503/spring-data-jpa-detached-entity by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] 런타임시 봄에 추가 빈 설정 파일을로드하는 법 (0) | 2019.04.26 |
---|---|
[SPRING] ApplicationContextAware 구현 중 - ApplicationContext가 NULL 임 (0) | 2019.04.26 |
[SPRING] @WebMvcTest가 java.lang.IllegalStateException로 실패합니다 : ApplicationContext를로드하지 못했습니다. (0) | 2019.04.26 |
[SPRING] 봄 부트 프레임 워크에서 Tomcat이 생성 한 액세스 로그를 필터링하는 방법 (0) | 2019.04.26 |
[SPRING] web.xml의 CharacterEncodingFilter를 사용한 Spring 인코딩 (0) | 2019.04.26 |