为了账号安全,请及时绑定邮箱和手机立即绑定

杰克逊 ObjectMapper 休眠问题

杰克逊 ObjectMapper 休眠问题

收到一只叮咚 2022-01-19 09:11:33
我正在开发一个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}
查看完整描述

3 回答

?
qq_花开花谢_0

TA贡献1835条经验 获得超7个赞

简短的回答是否定的,不要试图那么聪明。手动创建 DTO 以控制任何延迟加载,然后在事务外的 DTO 上使用 Jackson。


长答案是肯定的,您可以覆盖 MappingJackson2HttpMessageConverter 并控制从实体调用哪些字段。


@Configuration

public class MixInWebConfig extends WebMvcConfigurationSupport {


    @Bean

    public MappingJackson2HttpMessageConverter customJackson2HttpMessageConverter2() {

        MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter();

        ObjectMapper objectMapper = new ObjectMapper();

        objectMapper.addMixIn(DTO1.class, FooMixIn.class);

        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

        jsonConverter.setObjectMapper(objectMapper);

        return jsonConverter;

    }


    @Override

    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {

        converters.add(customJackson2HttpMessageConverter2());

    }

}

然后


    @Override

    protected void processViews(SerializationConfig config, BeanSerializerBuilder builder) {

        super.processViews(config, builder);

        if (classes.contains(builder.getBeanDescription().getBeanClass())) {

            List<BeanPropertyWriter> originalWriters = builder.getProperties();

            List<BeanPropertyWriter> writers = new ArrayList<BeanPropertyWriter>();

            for (BeanPropertyWriter writer : originalWriters) {

                String propName = writer.getName();

                if (!fieldsToIgnore.contains(propName)) {

                    writers.add(writer);

                }

            }

            builder.setProperties(writers);

        }

    }

}


查看完整回答
反对 回复 2022-01-19
?
长风秋雁

TA贡献1757条经验 获得超7个赞

我只想补充一点,您可以直接从 JPQL 查询返回 DTO,而不是使用 Jackson。它避免了从数据库到对象的Order转换以及从Order对象到OrdersPreviewDTO对象的另一次转换。


例如,您需要更改存储库中的查询来执行此操作。它会是这样的:


public interface OrderRepository extends CrudRepository<Order, Long> {


    @Query("SELECT new OrdersPreviewDTO(o.order_number, o.created_on, o.total_amount)) FROM Order o WHERE o.user.email = ?1")

    List<OrdersPreviewDTO> findOrdersByUser(String email);

}


查看完整回答
反对 回复 2022-01-19
?
达令说

TA贡献1821条经验 获得超6个赞

如果OrdersPreviewDTO严格来说是你的Order类的一个子集,为什么不简单地使用@JsonView注解在你的控制器中自动创建一个简单的视图呢?例如,请参阅https://spring.io/blog/2014/12/02/latest-jackson-integration-improvements-in-spring

如果您需要用于输入和输出的 DTO,还可以考虑使用http://mapstruct.org/


查看完整回答
反对 回复 2022-01-19
  • 3 回答
  • 0 关注
  • 247 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号