我的实体User
和Event
彼此之间有many to many
个关系。如果我尝试将User对象从Controller返回到REST API,则会导致循环依赖。
我决定使用DTOs
我会使用List<Event>
代替List<Integer>
代表事件对象ID的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);
}
UserController中
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);
}
}
最后,我的 PropertyMap 类
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)
这是一个异常,如果我尝试使用rest来获取
grammar org.xtext.example.mydemo.MyDemo with org.eclipse.xtext.common.Terminals
generate myDemo "http://www.xtext.org/example/mydemo/MyDemo"
Model:
(elements+=DocComments)*
;
DocComments hidden(WS, OTHER):
start=StartComment name=VarComment? property=PropertyComment* end=EndComment
;
StartComment: '/**';
EndComment:'*/';
VarComment: key='@var' name=ID;
PropertyComment: key='@property' name=ID;
terminal OTHER: '*';
答案 0 :(得分:0)
我遇到了同样的问题 我通过将id包装在另一个对象中来实现它
public class UserDTO {
List<EventDTO> participatingEvents
/// getter setter
}
public class EventDTO {
private Long id;
// getter setter
}
你不需要任何propertyMap或转换器
UserDTO userDTO = modelmapper.map(user, UserDTO.class);
希望有所帮助
<强>已更新强>
您也可以使用转换器
public class UserMap extends PropertyMap<User, UserDTO> {
@Override
protected void configure() {
Converter<List<User>, List<Long>> converter = new AbstractConverter<List<User>, List<Long>>() {
List<Long> result = new ArrayList<>();
@Override
protected List<Long> convert(List<User> source) {
source.forEach(user -> result.add(user.getId()));
return result;
}
};
using(converter).map(source.getUsers(), destination.getUsers());
}
}