override id name generated by jackson-datatype-hibernate

1k Views Asked by At

Is it possible to override the name generated by jackson-datatype-hibernate Feature.SERIALIZE_IDENTIFIER_FOR_LAZY_NOT_LOADED_OBJECTS?

Currently it is serializing using full package name:

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

I want it to use id instead:

"client":{"id":1}

I am subclassing the ObjectMapper so maybe there is some method I can hook into

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

There are 3 best solutions below

0
On

I have the same problem, I think it caused by Hibernate's proxy.

I haven't a perfect solution recently, but you can solved it like this:

  1. get the id, then create a new com.test.domain.Client object and set back to parent. then you will get "client": {"id":1,...}

  2. Modify your entity, add one more id for just readable to the parent object, for example, clientId. Then you could avoid jackson to serialize the sub object. You will get {..., "clientId":1,...}

Hope some one can give more perfect solution.

2
On

I run into the same problem. I dig inside Jackson code and found out that if you create Hibernate4Module with Hibernate Mapping it should work.

So my solution looks as follows.

  1. Standard Spring SessionFactory definition somewhere in my XML config:

    <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
         ...
    </bean>
    
  2. I have custom Jackson object mapper defined also as a Spring bean:

    <bean class="my.own.HibernateAwareObjectMapper"/>
    
  3. Now the key part. You need to inject LocalSessionFactoryBean into 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);
    }
    

I believe that as this code runs only once it should not have any significant performance impact. If you don't have ObjectMapper defined as a Spring bean you should be able to achieve the same via ApplicationContextAware and getBean() method with this trick https://stackoverflow.com/a/2736147/380891.

0
On

I resolve it in my branch in github using @Id annotation.

you can use it (compile as jar file or use directly in code) or wait while my pull request merged and new version release