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

时间:2014-01-31 05:18:36

标签: java jackson jackson-modules

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

3 个答案:

答案 0 :(得分: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);
    }
    
  4. 我相信,由于此代码只运行一次,因此不应对性能产生任何重大影响。如果没有将ObjectMapper定义为Spring bean,那么你应该能够通过ApplicationContextAware和getBean()方法实现相同的技巧https://stackoverflow.com/a/2736147/380891

答案 1 :(得分:1)

我遇到同样的问题,我认为这是由Hibernate代理造成的。

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

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

  2. 修改您的实体,添加一个ID,以便只对父对象可读,例如clientId。然后你可以避免杰克逊序列化子对象。您将获得{..., "clientId":1,...}

  3. 希望有人可以提供更完美的解决方案。

答案 2 :(得分:0)

我使用@Id注释在my branch in github中解决了这个问题。

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