переопределить имя идентификатора, сгенерированное jackson-datatype-hibernate

Можно ли переопределить имя, сгенерированное функцией jackson-datatype-hibernate Feature.SERIALIZE_IDENTIFIER_FOR_LAZY_NOT_LOADED_OBJECTS?

В настоящее время он сериализуется с использованием полного имени пакета:

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

Я хочу, чтобы вместо этого использовался идентификатор:

"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);
    }   
}

person jax    schedule 31.01.2014    source источник


Ответы (3)


Я столкнулся с той же проблемой. Я копался в коде Джексона и обнаружил, что если вы создадите Hibernate4Module с Hibernate Mapping, он должен работать.

Итак, мое решение выглядит следующим образом.

  1. Стандартное определение Spring SessionFactory где-то в моей конфигурации XML:

    <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
         ...
    </bean>
    
  2. У меня есть собственный сопоставитель объектов Джексона, определенный также как компонент Spring:

    <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, вы сможете добиться того же с помощью ApplicationContextAware и метод getBean() с этим приемом https://stackoverflow.com/a/2736147/380891.

person arek    schedule 17.10.2014
comment
Похоже, это должно работать, но я не могу понять, как получить дескриптор localSessionFactoryBean в приложении весенней загрузки? - person chrismarx; 26.07.2016
comment
Ах, неважно, следуя совету здесь, я могу получить SessionFactory, а затем я могу просто передать его Mappings - stackoverflow.com/a /33881946/228369 - person chrismarx; 28.07.2016

У меня такая же проблема, я думаю, что это вызвано прокси Hibernate.

Недавно у меня не было идеального решения, но вы можете решить его следующим образом:

  1. получите идентификатор, затем создайте новый объект com.test.domain.Client и вернитесь к родительскому. тогда вы получите "client": {"id":1,...}

  2. Измените свою сущность, добавьте еще один идентификатор для только что читаемого родительского объекта, например, clientId. Тогда вы можете избежать jackson для сериализации подобъекта. Вы получите {..., "clientId":1,...}

Надеюсь, что кто-то может дать более совершенное решение.

person lifejoice    schedule 25.07.2014

Я решаю это в моей ветке на github, используя аннотацию @Id.

вы можете использовать его (скомпилировать как файл jar или использовать непосредственно в коде) или подождать, пока мой запрос на вытягивание объединен и выпущена новая версия

person Mohsen Kashi    schedule 17.03.2015