2017-05-12 4 views
0

내가 뭘 잘못하고 있는지 알 수 없지만, 분명히 최대 절전 모드와 간단한 OneToMany 관계를 만들 수 없습니다.JPA/Hibernate "simple"OneToMany Unidirictional/집합 지우기가 작동하지 않습니다.

DB에있는 표는 다음과 같습니다. enter image description here 관련 부분 만 표시하므로 질문이 부 풀리지 않습니다. 내 사용자

@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이 비어있는 경우 두 번째 검사로 실패합니다. 그것은 매개 변수가 여전히 설정되었음을 나타냅니다.

+0

CORE_USER_ROLE_PARAM을 저장하기 전에 사용자를 저장하십시오. –

+1

사용자에게'mappedBy = "user"'를 넣지 않았습니다.userRoleParams' 필드는 BIDIRECTIONAL 관계입니다. –

+0

@Stimpson :로드 할 사용자는 테스트 시작 부분에서 볼 수 있듯이 이미 존재하며 매개 변수가 비어 있는지 확인하기 위해 사용자를로드합니다. – kism3t

답변