我有实体User
,Event
它们之间有many to many
关系。如果我尝试将用户对象从 Controller 返回到 REST API,则会导致循环依赖。
我决定使用DTOs
我将使用的地方,而不是List<Event>
仅仅List<Integer>
代表事件对象的 id。
但是,如果我尝试创建 custom PropertyMap
,它就不起作用。你推荐不同的方法,怎么做?
事件实体
@Entity
@Table(name = "events")
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class Event extends AbstractEntity {
@ManyToMany(cascade = CascadeType.PERSIST)
@JoinTable(name = "event_participants",
joinColumns = @JoinColumn(name = "event_id"),
inverseJoinColumns = @JoinColumn(name = "user_id"))
private List<User> eventParticipants;
用户实体
@Entity
@Table(name = "users")
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class User extends AbstractEntity {
@ManyToMany(mappedBy = "eventParticipants")
private List<Event> participatingEvents;
用户控制器
@RestController
@RequestMapping("/users")
public class UserController extends AbstractController {
@Autowired
private UserService userService;
@Autowired
private ModelMapper modelMapper;
@RequestMapping(method = RequestMethod.GET, value = "/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
public UserDTO find(@PathVariable("id") Integer id) {
final User user = userService.find(id);
if (user == null) {
//TODO throw some exception
return null;
}
UserDTO userDTO = userToDTO(user);
return userDTO;
}
private UserDTO userToDTO(User user) {
modelMapper.addMappings(new UserMap());
return modelMapper.map(user, UserDTO.class);
}
最后,我的PropertyMap类
public class UserMap extends PropertyMap<User, UserDTO> {
@Override
protected void configure() {
map().setFirstName(source.getFirstName());
map().setLastName(source.getLastName());
map().setEmail(source.getEmail());
List<Integer> friendsDTO = new ArrayList<>();
for(User u : source.getFriends()){
friendsDTO.add(u.getId());
}
map().setFriends(friendsDTO);
List<Integer> participatingEventsDTO = new ArrayList<>();
for(Event e : source.getParticipatingEvents()){
participatingEventsDTO.add(e.getId());
}
map().setParticipatingEvents(participatingEventsDTO);
List<Integer> ownedEventsDTO = new ArrayList<>();
for(Event e : source.getOwnedEvents()){
ownedEventsDTO.add(e.getId());
}
map().setOwnedEvents(ownedEventsDTO);
List<Integer> commentsDTO = new ArrayList<>();
for(Comment c : source.getComments()){
commentsDTO.add(c.getId());
}
map().setComments(commentsDTO);
List<Integer> thingsDTO = new ArrayList<>();
for(ThingToTake t : source.getThingsToTakeList()){
thingsDTO.add(t.getId());
}
map().setThingsToTakeList(thingsDTO);
}
}
如果我尝试使用 rest 获取,这是一个例外:
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.modelmapper.ConfigurationException: ModelMapper configuration errors:
1) Invalid source method java.util.List.add(). Ensure that method has zero parameters and does not return void.
2) Invalid source method java.util.List.add(). Ensure that method has zero parameters and does not return void.
3) Invalid source method java.util.List.add(). Ensure that method has zero parameters and does not return void.
4) Invalid source method java.util.List.add(). Ensure that method has zero parameters and does not return void.
5) Invalid source method java.util.List.add(). Ensure that method has zero parameters and does not return void.
5 errors
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:982)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
root cause
org.modelmapper.ConfigurationException: ModelMapper configuration errors:
1) Invalid source method java.util.List.add(). Ensure that method has zero parameters and does not return void.
2) Invalid source method java.util.List.add(). Ensure that method has zero parameters and does not return void.
3) Invalid source method java.util.List.add(). Ensure that method has zero parameters and does not return void.
4) Invalid source method java.util.List.add(). Ensure that method has zero parameters and does not return void.
5) Invalid source method java.util.List.add(). Ensure that method has zero parameters and does not return void.
5 errors
org.modelmapper.internal.Errors.throwConfigurationExceptionIfErrorsExist(Errors.java:241)
org.modelmapper.internal.ExplicitMappingBuilder.visitPropertyMap(ExplicitMappingBuilder.java:229)
org.modelmapper.PropertyMap.configure(PropertyMap.java:380)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:483)
org.modelmapper.internal.ExplicitMappingBuilder.build(ExplicitMappingBuilder.java:195)
org.modelmapper.internal.TypeMapImpl.addMappings(TypeMapImpl.java:72)
org.modelmapper.internal.TypeMapStore.getOrCreate(TypeMapStore.java:101)
org.modelmapper.ModelMapper.addMappings(ModelMapper.java:93)
com.ear.tripplan.rest.UserController.userToDTO(UserController.java:50)
com.ear.tripplan.rest.UserController.find(UserController.java:39)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:483)
org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)
org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:114)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)