2

是否可以覆盖由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);
    }   
}
4

3 回答 3

2

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

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

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

    <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
         ...
    </bean>
    
  2. 我将自定义 Jackson 对象映射器也定义为 Spring bean:

    <bean class="my.own.HibernateAwareObjectMapper"/>
    
  3. 现在是关键部分。您需要将 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://stackoverflow.com/a/2736147/380891实现相同的目的。

于 2014-10-17T17:04:10.080 回答
1

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

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

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

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

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

于 2014-07-25T10:05:30.827 回答
0

我使用注释在 github 的分支中解决它。@Id

您可以使用它(编译为 jar 文件或直接在代码中使用)或等待我的拉取请求合并和新版本发布

于 2015-03-17T07:09:57.517 回答