2014-11-26 3 views
0

나는 Spring 프레임 워크를 사용하여 응용 프로그램을 작성 중이다. 내 엔터티 개체에 대한 dto 모델을 만들고 스프링 컨트롤러에서 사용하려고합니다. 어렵지는 않지만 데이터베이스의 테이블 사이에 관계가 있으며 엔터티 개체를 설정해야합니다.컬렉션이있는 DTO 객체를 생성하는 방법

사용자 엔티티

@Entity 
@Table(name = "users") 
public class User implements Serializable { 

    private static final long serialVersionUID = 1L; 
    @Id 
    @GeneratedValue 
    @Column(name = "id") 
    private Integer id; 
    @NotBlank 
    @NotNull 
    @Size(min = 3, max = 40) 
    @Column(name = "username") 
    private String username; 
    @NotBlank 
    @NotNull 
    @Size(min = 3, max = 40) 
    @Column(name = "password") 
    private String password; 
    @NotBlank 
    @NotNull 
    @Size(min = 3, max = 40) 
    @Column(name = "firstName") 
    private String firstName; 
    @NotBlank 
    @NotNull 
    @Size(min = 3, max = 40) 
    @Column(name = "lastName") 
    private String lastName; 
    @Size(min = 11, max = 11) 
    @Column(name = "personalId") 
    private String personalId; 
    @Size(max = 40) 
    @Column(name = "city") 
    private String city; 
    @Size(max = 40) 
    @Column(name = "address") 
    private String address; 
    @NotBlank 
    @NotNull 
    @Email 
    @Size(max = 40) 
    @Column(name = "email") 
    private String email; 
    @Size(min = 9, max = 9) 
    @Column(name = "phone") 
    private String phone; 
    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.EAGER) 
    private Set<UserRole> userRoleSet; 

user_roles 기업

@Entity 
@Table(name = "user_roles") 
public class UserRole implements Serializable { 

    private static final long serialVersionUID = 1L; 

    @Id 
    @GeneratedValue 
    @Column(name = "id") 
    private Integer id; 
    @NotNull 
    @Size(max = 40) 
    @Column(name = "name") 
    private String name; 
    @JoinColumn(name = "userId") 
    @ManyToOne(targetEntity = User.class) 
    private User user; 

표 사용자가 테이블을 USER_ROLE 많은에 관계를 가지고있다. 나는이 단체에 대한 DTO 객체 생성 :

객체 인 UserDTO

public class UserDto { 

    private Integer id; 
    @NotBlank 
    @NotNull 
    @Size(min = 3, max = 40) 
    private String username; 
    @NotBlank 
    @NotNull 
    @Size(min = 3, max = 40) 
    private String password; 
    @NotBlank 
    @NotNull 
    @Size(min = 3, max = 40) 
    private String firstName; 
    @NotBlank 
    @NotNull 
    @Size(min = 3, max = 40) 
    private String lastName; 
    @Size(min = 11, max = 11) 
    private String personalId; 
    @Size(min = 3, max = 40) 
    private String city; 
    @Size(min = 3, max = 40) 
    private String address; 
    @NotBlank 
    @NotNull 
    @Email 
    @Size(max = 40) 
    private String email; 
    @Size(min = 9, max = 9) 
    private String phone; 
    private Set<UserRoleDto> userRoleSetDto; 

userRoleDto을

public class UserRoleDto { 

    private Integer id; 
    @NotNull 
    @Size(min = 3, max = 40) 
    private String name; 
    private UserDto userDto; 

@SuppressWarnings("unchecked") 
@RequestMapping(value = "/admin/adminlist", method = RequestMethod.GET) 
public ModelAndView goAdminList() { 
    ModelAndView mav = new ModelAndView("admin/adminlist"); 
    List<UserDto> admins = prepareUserListDto(userService.getAdminList()); 
    mav.addObject("admins", admins); 
    return mav; 
} 

에서 사용자의 목록이있는 페이지로 리디렉션

내 컨트롤러 이 컨트롤러는 prepareU 메소드를 사용하여 userdto list에 사용자 목록을 준비합니다. erListDto :이 방법은 메서드 호출

private List<UserDto> prepareUserListDto(List<User> users) { 
    List<UserDto> userDtoList = null; 
    if (users != null && !users.isEmpty()) { 
     userDtoList = new ArrayList<UserDto>(); 
     UserDto userDto = null; 
     for (User user : users) { 
      userDto = new UserDto(); 
      userDto.setId(user.getId()); 
      userDto.setUsername(user.getUsername()); 
      userDto.setPassword(user.getPassword()); 
      userDto.setFirstName(user.getFirstName()); 
      userDto.setLastName(user.getLastName()); 
      userDto.setEmail(user.getEmail()); 
      userDto.setUserRoleSetDto(prepareUserRoleDtoSet(user 
        .getUserRoleSet())); 
      userDtoList.add(userDto); 
     } 
    } 
    return userDtoList; 
} 

이 userRoleDto

private Set<UserRoleDto> prepareUserRoleDtoSet(Set<UserRole> userRoles) { 
    Set<UserRoleDto> userRoleDtoSet = null; 
    if (userRoles != null && !userRoles.isEmpty()) { 
     userRoleDtoSet = new HashSet<UserRoleDto>(); 
     UserRoleDto userRoleDto = null; 
     for (UserRole userRole : userRoles) { 
      userRoleDto = new UserRoleDto(); 
      userRoleDto.setId(userRole.getId()); 
      userRoleDto.setName(userRole.getName()); 
      userRoleDto.setUserDto(prepareUserDto(userRole.getUser())); 
      userRoleDtoSet.add(userRoleDto); 
     } 
    } 
    return userRoleDtoSet; 
} 

에 userRole을 준비하지만,이 방법은 다시 방법에 호출 : 결론적으로

private UserDto prepareUserDto(User user) { 
    UserDto userDto = new UserDto(); 
    userDto.setId(user.getId()); 
    userDto.setUsername(user.getUsername()); 
    userDto.setPassword(user.getPassword()); 
    userDto.setFirstName(user.getFirstName()); 
    userDto.setLastName(user.getLastName()); 
    userDto.setEmail(user.getEmail()); 
    userDto.setUserRoleSetDto(prepareUserRoleDtoSet(user.getUserRoleSet())); 
    return userDto; 
} 

내가 관리자의 목록을 표시하려고 재귀 호출이 있는데이 오류가 발생합니다.

java.lang.StackOverflowError org.hibernate.collection.internal.PersistentSet.isEmpty(PersistentSet.java:166) pl.piotr.ibank.controller.AdminController.prepareUserRoleDtoSet(AdminController.java:170) pl.piotr.ibank.controller.AdminController.prepareUserDto(AdminController.java:139) pl.piotr.ibank.controller.AdminController.prepareUserRoleDtoSet(AdminController.java:177) pl.piotr.ibank.controller.AdminController.prepareUserDto(AdminController.java:139) pl.piotr.ibank.controller.AdminController.prepareUserRoleDtoSet(AdminController.java:177) pl.piotr.ibank.controller.AdminController.prepareUserDto(AdminController.java:139) pl.piotr.ibank.controller.AdminController.prepareUserRoleDtoSet(AdminController.java:177) pl.piotr.ibank.controller.AdminController.prepareUserDto(AdminController.java:139) pl.piotr.ibank.controller.AdminController.prepareUserRoleDtoSet(AdminController.java:177) pl.piotr.ibank.controller.AdminController.prepareUserDto(AdminController.java:139)

라인 139는 private UserDto prepareUserDto(User user) 방법에서 userDto.setUserRoleSetDto(prepareUserRoleDtoSet(user.getUserRoleSet()));이고, 라인 177은 private Set<UserRoleDto> prepareUserRoleDtoSet(Set<UserRole> userRoles) 방법에서 private UserDto prepareUserDto(User user)이다.

이 엔티티에 대한 dto 작성 방법은 무엇입니까? 제약이 없다면 이것은 쉽지만 엔티티는 사용자와 user_role 사이에 제약이 있으며 좋은 해결책을 모릅니다.

답변

1

매우 간단한 해결책은 userDto 속성을 UserRoleDto 클래스에서 완전히 제거하는 것입니다. 한 엔티티에서 다른 엔티티로 이동해야하는 엔티티 클래스와 달리 양방향 관계를 포함하는 클라이언트는 대개 사용자의 역할 만 가져야하며 역할의 사용자는 가져 오지 않아야합니다. 따라서 두 dtos 사이에 양방향 관계가 필요하지 않습니다.

2

UserDto와 UserRoleDto 사이에는 양방향 관계가 있습니다. 당신이 정말로 양방향 관계를 유지해야하는 경우

, 나는 다음과 같이 코드를 수정합니다 :

private UserDto prepareUserDto(User user) { 
    UserDto userDto = new UserDto(); 
    userDto.setId(user.getId()); 
    userDto.setUsername(user.getUsername()); 
    userDto.setPassword(user.getPassword()); 
    userDto.setFirstName(user.getFirstName()); 
    userDto.setLastName(user.getLastName()); 
    userDto.setEmail(user.getEmail()); 
    userDto.setUserRoleSetDto(prepareUserRoleDtoSet(user.getUserRoleSet(), userDto)); 
    return userDto; 
} 

는 이쪽 객체 인 UserDTO가 prepareUserRoleDtoSet에 생성되고 전달합니다.

private Set<UserRoleDto> prepareUserRoleDtoSet(Set<UserRole> userRoles, UserDto userDto) { 
    Set<UserRoleDto> userRoleDtoSet = null; 
    if (userRoles != null && !userRoles.isEmpty()) { 
     userRoleDtoSet = new HashSet<UserRoleDto>(); 
     UserRoleDto userRoleDto = null; 
     for (UserRole userRole : userRoles) { 
      userRoleDto = new UserRoleDto(); 
      userRoleDto.setId(userRole.getId()); 
      userRoleDto.setName(userRole.getName()); 
      userRoleDto.setUserDto(userDto); 
      userRoleDtoSet.add(userRoleDto); 
     } 
    } 
    return userRoleDtoSet; 
} 
1

역할 모음에서 fetch = FetchType.EAGER 속성을 선언합니다. 그래서 hibernate가 User 일 때 그것의 UserRole 콜렉션은 이미 초기화되어있다. 그렇지 않은 경우에도 처음 호출 할 때 getUserRoleSet()으로 초기화됩니다. 당신은 간단하게 작성할 수 있습니다

private List<UserDto> prepareUserListDto(List<User> users) { 
    List<UserDto> userDtoList = null; 
    Set<UserRoleDto> roleDtoSet = null; 
    if (users != null && !users.isEmpty()) { 
     userDtoList = new ArrayList<UserDto>(); 
     UserDto userDto = null; 
     for (User user : users) { 
      userDto = new UserDto(); 
      userDto.setId(user.getId()); 
      userDto.setUsername(user.getUsername()); 
      userDto.setPassword(user.getPassword()); 
      userDto.setFirstName(user.getFirstName()); 
      userDto.setLastName(user.getLastName()); 
      userDto.setEmail(user.getEmail()); 
      roleDtoSet = new HashSet<UserRoleDto>(); 
      for (UserRole role: user.getUserRoleSet) { 
       UserRoleDto roleDto = new UserRoleDto(); 
       roleDto.setId(role.getId()); 
       roleDto.setUserDto(userDto); 
       roleDto.setName(user.getName); 
       roleDtoSet.add(roleDto); 
      } 
      userDto.setUserRoleSetDto(roleDtoSet); 
      userDtoList.add(userDto); 
     } 
    } 
    return userDtoList; 
} 

당신이 작은 방법을 prefere 경우 (작성하고 테스트하기 쉬운), 당신이 그것을 분할 당신이 쓴하지만 userDto을 통과 당신은 이미 거의 동일 할 수

private List<UserDto> prepareUserListDto(List<User> users) { 
    List<UserDto> userDtoList = null; 
    if (users != null && !users.isEmpty()) { 
     userDtoList = new ArrayList<UserDto>(); 
     UserDto userDto = null; 
     for (User user : users) { 
      userDto = new UserDto(); 
      userDto.setId(user.getId()); 
      userDto.setUsername(user.getUsername()); 
      userDto.setPassword(user.getPassword()); 
      userDto.setFirstName(user.getFirstName()); 
      userDto.setLastName(user.getLastName()); 
      userDto.setEmail(user.getEmail()); 
      userDto.setUserRoleSetDto(prepareUserRoleDtoSet(userDto, user 
        .getUserRoleSet())); 
      userDtoList.add(userDto); 
     } 
    } 
    return userDtoList; 
} 

private Set<UserRoleDto> prepareUserRoleDtoSet(UserDto userDto, 
     Set<UserRole> userRoles) { 
    Set<UserRoleDto> userRoleDtoSet = null; 
    if (userRoles != null && !userRoles.isEmpty()) { 
     userRoleDtoSet = new HashSet<UserRoleDto>(); 
     UserRoleDto userRoleDto = null; 
     for (UserRole userRole : userRoles) { 
      userRoleDto = new UserRoleDto(); 
      userRoleDto.setId(userRole.getId()); 
      userRoleDto.setName(userRole.getName()); 
      userRoleDto.setUserDto(userDto); 
      userRoleDtoSet.add(userRoleDto); 
     } 
    } 
    return userRoleDtoSet; 
} 

이렇게하면 모든 순환 의존성을 피할 수 있습니다.

관련 문제