杰克逊 ObjectMapper 休眠问题

我正在开发一个Spring Boot 2.0 / Java 8购物车在线应用程序。我Hibernate用作ORM框架。我有两个实体,Order如下OrderDetail所示:


@Entity

@Table(name = "orders")

public class Order extends AbstractEntityUuid {


    @Column(name = "order_number", unique = true)

    private String orderNumber;


    @JsonBackReference

    @ManyToOne(fetch = FetchType.LAZY)

    @JoinColumn(name = "user_id", nullable = false)

    private User user;


    @Column(name = "total_amount")

    private BigDecimal totalAmount = BigDecimal.ZERO;


    @CreatedDate

    @Column(name = "created_on", columnDefinition = "DATETIME", updatable = false)

    protected LocalDateTime created;


    @OneToMany(mappedBy = "order", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)

    @JsonManagedReference

    private Set<OrderDetail> items = new HashSet<>();


    @OneToOne(fetch = FetchType.LAZY, orphanRemoval = true)

    @JoinColumn(nullable = false, name = "card_details_id")

    private CardDetails card;


    @OneToOne(fetch = FetchType.LAZY, orphanRemoval = true)

    @JoinColumn(nullable = false, name = "shipping_address_id")

    private Address shippingAddress;


    @OneToOne(fetch = FetchType.LAZY, orphanRemoval = true)

    @JoinColumn(name = "billing_address_id")

    private Address billingAddress;


    //getters and setters

}


@Entity

@Table(name = "order_detail")

public class OrderDetail extends AbstractPersistable<Long> {


    @Column(name = "quantity")

    private Integer quantity;


    @Column(name = "total_amount")

    private BigDecimal totalAmount = BigDecimal.ZERO;


    @ManyToOne(fetch = FetchType.LAZY)

    @JoinColumn(name = "order_id", nullable = false)

    @JsonBackReference

    private Order order;


    @OneToOne(fetch = FetchType.LAZY)

    @JoinColumn(name = "product_id", nullable = false)

    private Product product;


    //getters and setters

}


收到一只叮咚
浏览 248回答 3
3回答

qq_花开花谢_0

简短的回答是否定的,不要试图那么聪明。手动创建 DTO 以控制任何延迟加载,然后在事务外的 DTO 上使用 Jackson。长答案是肯定的,您可以覆盖 MappingJackson2HttpMessageConverter 并控制从实体调用哪些字段。@Configurationpublic class MixInWebConfig extends WebMvcConfigurationSupport {&nbsp; &nbsp; @Bean&nbsp; &nbsp; public MappingJackson2HttpMessageConverter customJackson2HttpMessageConverter2() {&nbsp; &nbsp; &nbsp; &nbsp; MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter();&nbsp; &nbsp; &nbsp; &nbsp; ObjectMapper objectMapper = new ObjectMapper();&nbsp; &nbsp; &nbsp; &nbsp; objectMapper.addMixIn(DTO1.class, FooMixIn.class);&nbsp; &nbsp; &nbsp; &nbsp; objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);&nbsp; &nbsp; &nbsp; &nbsp; jsonConverter.setObjectMapper(objectMapper);&nbsp; &nbsp; &nbsp; &nbsp; return jsonConverter;&nbsp; &nbsp; }&nbsp; &nbsp; @Override&nbsp; &nbsp; public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {&nbsp; &nbsp; &nbsp; &nbsp; converters.add(customJackson2HttpMessageConverter2());&nbsp; &nbsp; }}然后&nbsp; &nbsp; @Override&nbsp; &nbsp; protected void processViews(SerializationConfig config, BeanSerializerBuilder builder) {&nbsp; &nbsp; &nbsp; &nbsp; super.processViews(config, builder);&nbsp; &nbsp; &nbsp; &nbsp; if (classes.contains(builder.getBeanDescription().getBeanClass())) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; List<BeanPropertyWriter> originalWriters = builder.getProperties();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; List<BeanPropertyWriter> writers = new ArrayList<BeanPropertyWriter>();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for (BeanPropertyWriter writer : originalWriters) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String propName = writer.getName();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (!fieldsToIgnore.contains(propName)) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; writers.add(writer);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; builder.setProperties(writers);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}

长风秋雁

我只想补充一点,您可以直接从 JPQL 查询返回 DTO,而不是使用 Jackson。它避免了从数据库到对象的Order转换以及从Order对象到OrdersPreviewDTO对象的另一次转换。例如,您需要更改存储库中的查询来执行此操作。它会是这样的:public interface OrderRepository extends CrudRepository<Order, Long> {&nbsp; &nbsp; @Query("SELECT new OrdersPreviewDTO(o.order_number, o.created_on, o.total_amount)) FROM Order o WHERE o.user.email = ?1")&nbsp; &nbsp; List<OrdersPreviewDTO> findOrdersByUser(String email);}

达令说

如果OrdersPreviewDTO严格来说是你的Order类的一个子集,为什么不简单地使用@JsonView注解在你的控制器中自动创建一个简单的视图呢?例如,请参阅https://spring.io/blog/2014/12/02/latest-jackson-integration-improvements-in-spring。如果您需要用于输入和输出的 DTO,还可以考虑使用http://mapstruct.org/
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java