微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在 Hibernate 中使用 Spring boot 配置的 Jackson Objectmapper

如何解决在 Hibernate 中使用 Spring boot 配置的 Jackson Objectmapper

我想将 Hibernate 配置为使用 Spring 创建的 Jackson 的 Objectmapper 在 json 和实体之间进行映射。在我正在处理的项目中,我已经将 Jooq 配置为使用 Spring 的 ObjectMapper,但是我在如何配置 Hibernate 以使用它时遇到了麻烦。 目标最终是让 Jooq 和 Hibernate 使用相同的 ObjectMapper

我检查了弗拉德的这个article。不幸的是,文章中给出的所有技巧都不适用于我正在从事的项目。

这是我尝试过的示例配置

@Configuration
public class HibernateConfiguration implements HibernatePropertiesCustomizer {
    //Autowire Objectmapper created by Spring
    @Autowired
    ObjectMapper objectMapper;

    @Override
    public void customize(Map<String,Object> hibernateProperties) {
        ObjectMappersupplier objectMappersupplier = () -> objectMapper;
        // Below config doesn't work since Hibernate types creates it's own mapper
        hibernateProperties.put("hibernate.types.jackson.object.mapper",objectMappersupplier);
}

也尝试了相同的方法,将 Objectmapper 添加到 hibernate-types.properties。

#Used by Hibernate but cannot get reference of Spring managed ObjectMapper since this is class is called outside of Spring's context.
hibernate.types.jackson.object.mapper=path.to.ObjectMappersupplier

我使用的另一种方法,但在从 JSON 转换为 NullpointerException 类中的实体时失败并显示 JsonTypeDescriptor

@Configuration
public class HibernateConfiguration implements HibernatePropertiesCustomizer{

    @Autowired
    ObjectMapper objectMapper;

    @Override
    public void customize(Map<String,Object> hibernateProperties) {
        // Underlying implementation needs some JavaType or propertyClass,otherwise when converting 
        // from JSON we get a nullpointer.
        var jsonBinaryType = new JsonBinaryType(objectMapper);
        hibernateProperties.put("hibernate.type_contributors",(TypeContributorList) () -> 
        Collections.singletonList((typeContributions,serviceRegistry) -> 
                      typeContributions.contributeType(jsonBinaryType)));
}

以下是实体超类的类型声明。

// This makes Hibernate types create it's own mapper.
@TypeDef(name = "jsonb",typeClass = JsonBinaryType.class)
@MappedSuperclass
public abstract class Entity{

}

那么,是否有任何可能的解决方案可以将 Spring 管理的 ObjectMapper 连接到 Hibernate?

解决方法

我终于想通了,但这是一个创造性的解决方案......

TLDR:我有一个 bean,它将 Spring 配置的 objectMapper 存储在静态字段中。 BeanFactoryPostProcessor 确保在 Hibernate(类型)尝试加载/获取 ObjectMapper 之前初始化此 bean。

hibernate.properties

hibernate.types.jackson.object.mapper=com.github.lion7.example.HibernateObjectMapperSupplier

HibernateObjectMapperSupplier.kt

package com.github.lion7.example

import com.fasterxml.jackson.databind.ObjectMapper
import com.vladmihalcea.hibernate.type.util.ObjectMapperSupplier
import org.springframework.beans.factory.config.BeanFactoryPostProcessor
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory
import org.springframework.stereotype.Component

class HibernateObjectMapperSupplier : ObjectMapperSupplier {
    override fun get(): ObjectMapper =
        ObjectMapperHolder.objectMapper
}

@Component
class ObjectMapperHolder(objectMapper: ObjectMapper) {

    companion object {
        lateinit var objectMapper: ObjectMapper
    }

    init {
        Companion.objectMapper = objectMapper
    }

}

@Component
class ObjectMapperDependencyFixer : BeanFactoryPostProcessor {
    override fun postProcessBeanFactory(beanFactory: ConfigurableListableBeanFactory) {
        val beanDefinition = beanFactory.getBeanDefinition("entityManagerFactory")
        val oldDependsOn = beanDefinition.dependsOn ?: emptyArray()
        val newDependsOn = oldDependsOn + "objectMapperHolder"
        beanDefinition.setDependsOn(*newDependsOn)
    }
}

与要点相同的代码:https://gist.github.com/lion7/c8006b69a309e38183deb69124b888b5

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?