@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["metricIdFields"])
使用@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,可能会有不愉快的意外
@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["metricIdFields"])
使用@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,可能会有不愉快的意外