@BasePathAwareController 异常:无法初始化代理 - 无会话

@BasePathAwareController Exception: could not initialize proxy - no Session

@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()
        );
    }
}

由于SpringData 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在class中应该写成@RequestMapping。

我不知道为什么。如果你知道原因请教教我。

@BasePathAwareController
@RequestMapping(value = "your url value")
public class MetricController {}

如果您检查 @BasePathAwareController 的来源,您会发现它 而不是 注释 @Controller。 因此,如果 class 仅使用 @BasePathAwareController 注释,则默认情况下 SpringMvc 和 RepositoryRestMvc.

都不会选择它

前者选择classes注释为@Controller@RequestMapping,后者只选择注释为classes @RepositoryRestController.

因此,再次说明一下:@BasePathAwareController 而不是 @Controller 的 'extension',它只是一个额外的 'sign'注解。 您也可以将 @Controller@BasePathAwareController 一起使用,而不是 @RequestMapping

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

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

如果您需要在 controller-class.

中实现更复杂的 handler-methods,可能会有不愉快的意外