Hibernate @Entity конфликтует с Spring @Autowired для объекта, не являющегося столбцом - PullRequest
1 голос
/ 25 марта 2020

У меня есть таблица, которая содержит описания предметов. Предметы имеют ценовую историю, которая может быть очень обширной. Это последний момент, который заставляет меня избегать использования обычного отображения Hibernate «один ко многим» с отложенной загрузкой. Подумайте о ценовой истории, как тики на бирже, лоты истории.

Итак, у меня есть кеш, который работает хорошо, все подключено к Spring, DAO внедряется, кеш управляет тем, что нужно запрашивать, а не тем, что он уже знает.

Итак, " Естественная вещь - это возможность спросить предмет об истории цен. Вот некоторый код, который является уменьшенной версией реальной вещи:

@Entity @Table(name="item")
public class Item {
    @Id
    @Column(name="id")
    private long id;
    @Column(name="name")
    private String name;

    @Autowired
    private PriceCache priceCache;

    /* ...setters, getters for id, name ... */

    public NavigableMap<LocalDateTime,SecurityValue> getPrices(LocalDateTime begTime, LocalDateTime endTime) {
        return priceCache.get(id, begTime, endTime);
    }
}

Моя оригинальная версия использовала все методы stati c с PriceCache; Я хочу переключиться на использование внедренного компонента частично, потому что это будет означать, что я могу переписать кэш как реализацию интерфейса, который упрощает настройку модульных тестов для некоторых битов, которых нет в примере; Я могу создать тестовый объект кеша, который предоставляет мою ценовую историю любым способом, который мне нужен для теста, даже не обращаясь к базе данных.

Проблема в том, что когда Spring и Hibernate сканируют пакеты, они, кажется, конфликтуют из-за что делать с этим полем @Autowired; Я получаю следующее с некоторым форматированием для удобства чтения); dbEMF - это мой EntityManagerFactory:

Exception in thread "main" org.springframework.beans.factory.BeanCreationException:
   Error creating bean with name 'dbEMF' defined in class path resource [applicationContext.xml]:
     Invocation of init method failed;
   nested exception is javax.persistence.PersistenceException:
     [PersistenceUnit: default] Unable to build Hibernate SessionFactory;
   nested exception is org.hibernate.MappingException:
     Could not determine type for: com.example.cache.PriceCache, at table: item, for columns: [org.hibernate.mapping.Column(priceCache)]

Опять же, базовый код c и кэш работают нормально, если я использую только методы stati c с PriceCache, где я создаю его как одиночный «вручную». Преобразование, чтобы Spring мог обрабатывать создание и внедрение в других местах, тоже работает отлично. Только когда у меня есть это сочетание Hibernate и Spring, я сталкиваюсь с проблемой.

Я не пытался вернуться к использованию внешнего файла XML для конфигурации hibernate, который мог бы решить проблему, или нет.

Есть ли способ сообщить Hibernate, что это не столбец? Или есть другой шаблон, которому я должен следовать, чтобы делать подобные вещи, может быть, какой-то прокси для объектов Item?

Ответы [ 2 ]

3 голосов
/ 25 марта 2020

вы можете использовать аннотацию @Transient, чтобы указать, что она не должна сохраняться в БД.

Вообще говоря, я думаю, что если это сущность, у нее не должно быть какого-либо автоматического кеша, который не является ее частью, но это другая история

0 голосов
/ 26 марта 2020

Относительно обсуждения в ответе ниже. Коллекции и сущности Hibernate являются объектами прокси. Возможно, вы можете попытаться реализовать собственный HibernateProxy, который будет управлять вашей коллекцией. В соответствии с документами это представляется возможным (CustomProxies), но я никогда не делал это проверить здесь: https://docs.jboss.org/hibernate/orm/5.4/userguide/html_single/Hibernate_User_Guide.html#entity -proxy

...