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

时间:2019-05-20 09:14:14

标签: java spring spring-data-rest

@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正常工作。 问题是什么?它可以解决吗?

2 个答案:

答案 0 :(得分:0)

我解决了。

要共享,@ BasePathAwareController应该在类中写为@RequestMapping。

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

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

答案 1 :(得分:0)

如果您检查@BasePathAwareController的来源,那么您会发现它没有注释为@Controller。 因此,如果仅用@BasePathAwareController注释类,则默认SpringMvc和RepositoryRestMvc都不会选择它。

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

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

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

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

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