У меня есть сущности User
и Event
которые имеют отношение . Если я попытаюсь вернуть объект User из Controller в REST API, это приведет к циклической зависимости.Модель mapper - как карта несовместимых типов
Я решил использовать DTOs
, где я бы использовал вместо List<Event>
только List<Integer>
, который будет представлять идентификаторы объектов событий.
Но если я попытаюсь создать пользовательский номер PropertyMap
, он не работает. Вы рекомендуете другой подход, как это сделать?
объект Event
@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;
UserController
@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);
}
}
Это исключение я получу, если я пытаюсь получить с помощью отдыха:
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)
Вы можете указать "Не работает"? Есть ли исключение? Или это ничего? Пробовали ли вы конвертацию в автономной среде? Используете ли вы некоторую (Hibernate) ленивую инициализацию (и, следовательно, список не инициализируется в этой точке)? –
Я отредактирую вопрос на добавление исключения. –
Мое предположение заключается в том, что вы не можете использовать реальное преобразование (реализация (для каждого добавления)) для списков в mapper, и вместо этого вы определили конвертер или вызовите картупер во второй раз. ('using (converter) .map(). setListe (source.getList());') (IMO этот конвертер просто добавляет много сложности, вам не нужно, и вам будет лучше, если вы сделаете полное преобразование самостоятельно.) –