0
내가 뭘 잘못하고 있는지 알 수 없지만, 분명히 최대 절전 모드와 간단한 OneToMany 관계를 만들 수 없습니다.JPA/Hibernate "simple"OneToMany Unidirictional/집합 지우기가 작동하지 않습니다.
DB에있는 표는 다음과 같습니다. 관련 부분 만 표시하므로 질문이 부 풀리지 않습니다. 내 사용자
@Entity(name = "CORE_USER")
public class User extends AbstractPersistentObject {
...
@ManyToMany(cascade=CascadeType.ALL,fetch=FetchType.LAZY)
@JoinTable(name = "CORE_USER_TO_ROLE",
joinColumns = { @JoinColumn(name = "USER_ID") },
inverseJoinColumns = { @JoinColumn(name = "ROLE_ID") })
private Set<UserRole> roles = new HashSet<UserRole>();
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "USER_ID")
private Set<UserRoleParam> userRoleParams = new HashSet<UserRoleParam>();
...(getter and setters)
}
여기에 핵심 사용자 역할 PARAM 엔티티처럼 보이는
@Entity(name = "CORE_USER_ROLE_PARAM")
public class UserRoleParam extends AbstractPersistentObject {
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "ROLE_ID")
private UserRole userRole;
@Column(name = "ROLE_PARAMETER")
private String paramter;
...(getter and setter)....
}
UserRole 엔티티
@Entity(name="CORE_USER_ROLE")
public class UserRole extends AbstractPersistentObject {
@Enumerated(EnumType.STRING)
@Column(name = "ROLE_NAME", length = 30, nullable=false, unique=true)
private UserRoleEnum roleName;
...(getter and setters)
}
내 시험에서이 작업을 수행 할 때 :
@Test
@Transactional(propagation = Propagation.NEVER)
public void saveUserRoleParametersTest() throws Exception {
// load an user which exists and check params is zero
UserDTO userDTO = userService.getUserDTO(Users.DE678_ACTIVE_ALLROLES.getObject().getId());
Assert.assertNotNull(userDTO);
Assert.assertNotNull(userDTO.getUserRoleParams());
Assert.assertEquals(0, userDTO.getUserRoleParams().size());
Map<UserRoleEnum, List<String>> userRoleParams = new HashMap<>();
userRoleParams.put(UserRoleEnum.BASIC, new ArrayList<>());
userRoleParams.get(UserRoleEnum.BASIC).add("BASIC_PARAM");
// save params to user
userService.saveUserRoleParameters(Users.DE678_ACTIVE_ALLROLES.getObject().getId(), userRoleParams);
userDTO = userService.getUserDTO(Users.DE678_ACTIVE_ALLROLES.getObject().getId());
Assert.assertNotNull(userDTO);
Assert.assertNotNull(userDTO.getUserRoleParams());
Assert.assertEquals(1, userDTO.getUserRoleParams().size());
Assert.assertEquals(1, userDTO.getUserRoleParams().get(UserRoleEnum.BASIC).size());
Assert.assertTrue(userDTO.getUserRoleParams().get(UserRoleEnum.BASIC).contains("BASIC_PARAM"));
// delete params of user
userService.saveUserRoleParameters(Users.DE678_ACTIVE_ALLROLES.getObject().getId(), null);
userDTO = userService.getUserDTO(Users.DE678_ACTIVE_ALLROLES.getObject().getId());
Assert.assertNotNull(userDTO);
Assert.assertNotNull(userDTO.getUserRoleParams());
Assert.assertEquals(0, userDTO.getUserRoleParams().size());
}
그녀
DEBUG [main] 12.05.17 08:46:50.264 [email protected]: select user0_.id as id1_0_0_, user0_.version as version2_0_0_, user0_.ACTIVE as ACTIVE1_38_0_, user0_.APP_LANG as APP_LANG2_38_0_, user0_.DEFAULT_MODULE as DEFAULT_3_38_0_, user0_.ORGA_UNIT as ORGA_UNI4_38_0_, user0_.USER_FULL_NAME as USER_FUL5_38_0_, user0_.USER_NAME as USER_NAM6_38_0_ from CORE_USER user0_ where user0_.id=?
DEBUG [main] 12.05.17 08:46:50.270 [email protected]: select userrole0_.id as id1_0_, userrole0_.version as version2_0_, userrole0_.ROLE_NAME as ROLE_NAM1_41_ from CORE_USER_ROLE userrole0_ where userrole0_.ROLE_NAME in (?)
DEBUG [main] 12.05.17 08:46:50.287 [email protected]: select userrolepa0_.USER_ID as USER_ID3_0_0_, userrolepa0_.id as id1_42_0_, userrolepa0_.id as id1_0_1_, userrolepa0_.version as version2_0_1_, userrolepa0_.ROLE_PARAMETER as ROLE_PAR1_42_1_, userrolepa0_.ROLE_ID as ROLE_ID2_42_1_ from CORE_USER_ROLE_ROLE_PARAM userrolepa0_ where userrolepa0_.USER_ID=?
DEBUG [main] 12.05.17 08:46:50.290 [email protected]: insert into CORE_USER_ROLE_PARAM (version, ROLE_PARAMETER, ROLE_ID, id) values (?, ?, ?, ?)
WARN [main] 12.05.17 08:46:50.291 [email protected]: SQL Error: 23502, SQLState: 23502
ERROR [main] 12.05.17 08:46:50.291 [email protected]: NULL nicht zulässig für Feld "USER_ID"
NULL not allowed for column "USER_ID"; SQL statement:
insert into CORE_USER_ROLE_ROLE_PARAM (version, ROLE_PARAMETER, ROLE_ID, id) values (?, ?, ?, ?) [23502-175]
WARN [main] 12.05.17 08:46:50.291 [email protected]: SQL Error: 23502, SQLState: 23502
ERROR [main] 12.05.17 08:46:50.292 [email protected]: NULL nicht zulässig für Feld "USER_ID"
NULL not allowed for column "USER_ID"; SQL statement:
:
@Override
public void saveUserRoleParameters(final String userId, final Map<UserRoleEnum, List<String>> userRoleParams) throws UserNotFoundException {
User user = userDAO.get(userId);
if (user == null) {
throw new UserNotFoundException(userId);
}
if (userRoleParams == null || userRoleParams.isEmpty()) {
user.getUserRoleParams().clear();
} else {
List<UserRole> roles = userDAO.getUserRolesByEnums(userRoleParams.keySet());
Map<UserRoleEnum, UserRole> enumToEntity = new HashMap<>();
roles.stream().forEach(r -> enumToEntity.put(r.getRoleName(), r));
for (Entry<UserRoleEnum, List<String>> entry : userRoleParams.entrySet()) {
UserRoleParam urp = new UserRoleParam(enumToEntity.get(entry.getKey()), entry.getValue().stream().collect(Collectors.joining(";")));
user.getUserRoleParams().add(urp);
}
}
userDAO.saveOrUpdate(user);
}
문제는 내 테스트는 saveUserRoleParameters
의 첫 번째 서비스 메서드 호출 (: 지금 SQL 로그가 활성화 된 EDIT)에 실패 할 수 있습니다 : 전자 내가 호출 사용자 서비스 방법도
사용자 ID가 속한 곳에 UserID를 넣지 않아야합니까? 내가 원하는 것은 사용자가 UserRoleParams에 대해 알고 있지만 다른 방향으로는 알지 못하는 단방향 관계입니다. 여기의 예와 같이 http://www.objectdb.com/api/java/jpa/annotations/relationship
편집 # 2 : 해결책을 찾았습니다. 사용자 엔터티에서 다음을 추가했습니다.
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "USER_ID", nullable = false)
private Set<UserRoleParam> userRoleParams = new HashSet<UserRoleParam>();
이제는 설정을 지우는 것이 유지되지 않을 것입니다. Set
이 비어있는 경우 두 번째 검사로 실패합니다. 그것은 매개 변수가 여전히 설정되었음을 나타냅니다.
CORE_USER_ROLE_PARAM을 저장하기 전에 사용자를 저장하십시오. –
사용자에게'mappedBy = "user"'를 넣지 않았습니다.userRoleParams' 필드는 BIDIRECTIONAL 관계입니다. –
@Stimpson :로드 할 사용자는 테스트 시작 부분에서 볼 수 있듯이 이미 존재하며 매개 변수가 비어 있는지 확인하기 위해 사용자를로드합니다. – kism3t