BasePathAwareController

BasePathAwareController

@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[&quot;metricIdFields&quot;])


使用@RepositoryRestController可以正常工作。
问题是什么?它可以解决吗?

最佳答案

如果检查@BasePathAwareController的来源,则可以看到它没有用@Controller注释。
因此,如果仅使用@BasePathAwareController注释类,则默认SpringMvc和RepositoryRestMvc都不会选择该类。

前者选择使用@Controller@RequestMapping注释的类,后者仅选择使用@RepositoryRestController注释的类。

再次说明一下:@BasePathAwareController不是@Controller的“扩展名”,它只是附加的“符号”注解。
您也可以将@Controller@BasePathAwareController一起使用,而不是@RequestMapping

我认为这是一种误导性的命名,或者仅仅是实现中的一个错误。

还有一件事。
如果将@RepositoryRestController切换为@Controller / @RequestMapping,则将以完全不同的方式处理控制器。
看起来它的工作方式相同,但是由完全不同的handlerMapping调用:它使用不同的转换器,argumentResolvers甚至不同的objectMapper。

如果您需要在控制器类中实现更复杂的处理程序方法,可能会有令人不愉快的惊喜。

10-06 05:44