覆盖由 jackson-datatype-hibernate 生成的 id 名称

Posted

技术标签:

【中文标题】覆盖由 jackson-datatype-hibernate 生成的 id 名称【英文标题】:override id name generated by jackson-datatype-hibernate 【发布时间】:2014-02-23 17:25:30 【问题描述】:

是否可以覆盖 jackson-datatype-hibernate Feature.SERIALIZE_IDENTIFIER_FOR_LAZY_NOT_LOADED_OBJECTS 生成的名称?

目前它正在使用完整的包名进行序列化:

"client":"com.test.domain.Client":1

我希望它使用 id 代替:

"client":"id":1

我正在对 ObjectMapper 进行子类化,所以也许有一些我可以挂钩的方法

public class HibernateAwareObjectMapper extends ObjectMapper 

    public HibernateAwareObjectMapper() 
        Hibernate4Module hbm = new Hibernate4Module();
        hbm.configure(Feature.SERIALIZE_IDENTIFIER_FOR_LAZY_NOT_LOADED_OBJECTS, true);
        registerModule(hbm);
       

【问题讨论】:

【参考方案1】:

我在my branch in github 中使用@Id 注释解决了它。

您可以使用它(编译为jar文件或直接在代码中使用)或等待my pull request合并和新版本发布

【讨论】:

【参考方案2】:

我遇到了同样的问题。我深入研究了 Jackson 代码,发现如果您使用 Hibernate Mapping 创建 Hibernate4Module,它应该可以工作。

所以我的解决方案如下所示。

    我的 XML 配置中某处的标准 Spring SessionFactory 定义:

    <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
         ...
    </bean>
    

    我将自定义 Jackson 对象映射器也定义为 Spring bean:

    <bean class="my.own.HibernateAwareObjectMapper"/>
    

    现在是关键部分。您需要将 LocalSessionFactoryBean 注入 ObjectMapper:

    @Autowired
    public HibernateAwareObjectMapper(LocalSessionFactoryBean sessionFactoryBean) 
        Hibernate4Module hibernate4Module = new Hibernate4Module(sessionFactoryBean.getConfiguration().buildMapping());
        hibernate4Module.configure(Hibernate4Module.Feature.SERIALIZE_IDENTIFIER_FOR_LAZY_NOT_LOADED_OBJECTS, true);
        registerModule(hibernate4Module);
    
    

我认为,由于此代码仅运行一次,因此不会对性能产生任何重大影响。如果您没有将 ObjectMapper 定义为 Spring bean,您应该能够通过 ApplicationContextAware 和 getBean() 方法使用此技巧 https://***.com/a/2736147/380891 实现相同的目的。

【讨论】:

这看起来应该可以工作,但我不知道如何在 Spring Boot 应用程序中获取 localSessionFactoryBean 的句柄? 啊,没关系,按照这里的建议,我可以获得 SessionFactory,然后我可以将其转换为 Mappings - ***.com/a/33881946/228369【参考方案3】:

我也有同样的问题,我认为是Hibernate的代理引起的。

我最近还没有完美的解决方案,但是你可以这样解决:

    获取 id,然后创建一个新的 com.test.domain.Client 对象并设置回父对象。然后你会得到"client": "id":1,...

    修改您的实体,再添加一个 id 以供父对象读取,例如,clientId。然后你可以避免杰克逊序列化子对象。你会得到..., "clientId":1,...

希望有人能给出更完美的解决方案。

【讨论】:

以上是关于覆盖由 jackson-datatype-hibernate 生成的 id 名称的主要内容,如果未能解决你的问题,请参考以下文章

如何合并由最新覆盖的哈希数组?

如何覆盖由 jquery/javascript 设置的 css 高度?

如何覆盖由 IdentityServer3.accesstokenvalidation 引起的服务耦合

覆盖由 jackson-datatype-hibernate 生成的 id 名称

由 MasterViewController 的 UITableView 覆盖的 UISplitViewController 下的 Banner Ads

无法覆盖由 TargetType 在单个特定控件上设置的全局 WPF 样式