@BasePathAwareController
public class MetricController {
@Autowired
private MetricRepository metricRepository;
@Transactional
@RequestMapping(method = RequestMethod.GET, value = "/metrics/in/{id}")
public @ResponseBody
MetricDTO getMetric(@PathVariable Long id) {
return MetricDTO.fromEntity(metricRepository.getOne(id));
}
}
@Entity
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Table(
uniqueConstraints = @UniqueConstraint(columnNames = {"metricType", "instanceType"}, name = "customUniqueId")
)
public class Metric implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(unique = true)
private String name;
private SourceType sourceType;
private String metricTypeField;
private String metricType;
private String instanceType;
private String instanceTypeField;
@ElementCollection
private List<String> metricIdFields;
@ElementCollection
private List<String> valueFields;
@ElementCollection
private Map<String, String> virtualFieldValueEx;
}
@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class MetricDTO {
private SourceType sourceType;
private String metricTypeField;
private String metricType;
private String instanceType;
private String instanceTypeField;
private List<String> metricIdFields;
private List<String> valueFields;
private Map<String, String> virtualFieldValueEx;
public static MetricDTO fromEntity(Metric metric) {
return new MetricDTO(
metric.getSourceType(),
metric.getMetricTypeField(),
metric.getMetricType(),
metric.getInstanceType(),
metric.getInstanceTypeField(),
metric.getMetricIdFields(),
metric.getValueFields(),
metric.getVirtualFieldValueEx()
);
}
}
由于Spring Data Rest中的@RepositoryRestController与Swagger不兼容,因此我将其更改为@BasePathAwareController。
因此,问题在于控制器无法正常工作。
错误历史如下。
Could not write JSON: failed to lazily initialize a collection of role: com.jmsight.management.entity.Metric.metricIdFields, could not initialize proxy - no Session; nested exception is com.fasterxml.jackson.databind.JsonMappingException: failed to lazily initialize a collection of role: com.jmsight.management.entity.Metric.metricIdFields, could not initialize proxy - no Session (through reference chain: com.jmsight.management.dto.MetricDTO["metricIdFields"])
使用@RepositoryRestController可以正常工作。
问题是什么?它可以解决吗?
最佳答案
如果检查@BasePathAwareController
的来源,则可以看到它没有用@Controller
注释。
因此,如果仅使用@BasePathAwareController
注释类,则默认SpringMvc和RepositoryRestMvc都不会选择该类。
前者选择使用@Controller
或@RequestMapping
注释的类,后者仅选择使用@RepositoryRestController
注释的类。
再次说明一下:@BasePathAwareController
不是@Controller
的“扩展名”,它只是附加的“符号”注解。
您也可以将@Controller
与@BasePathAwareController
一起使用,而不是@RequestMapping
。
我认为这是一种误导性的命名,或者仅仅是实现中的一个错误。
还有一件事。
如果将@RepositoryRestController
切换为@Controller
/ @RequestMapping
,则将以完全不同的方式处理控制器。
看起来它的工作方式相同,但是由完全不同的handlerMapping调用:它使用不同的转换器,argumentResolvers甚至不同的objectMapper。
如果您需要在控制器类中实现更复杂的处理程序方法,可能会有令人不愉快的惊喜。