Hibernate @Entity 与非列对象的 Spring @Autowired 冲突

Hibernate @Entity conflict with Spring @Autowired for non-column object

我有一个 table,其中包含项目描述。项目具有非常广泛的价格历史记录。正是最后一点导致我避免使用带有延迟加载的普通一对多 Hibernate 映射。将价格历史想象成证券交易所的滴答声, 的历史。

所以我有一个运行良好的缓存,它全部连接 Spring,DAO 被注入,缓存管理需要查询的内容与它已经知道的内容。

因此,"natural" 就是能够询问某件商品的价格历史记录。这是一些代码,它是真实事物的精简版:

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

我的原始版本使用 PriceCache 的所有静态方法;我想切换到使用注入的 bean,部分原因是这意味着我可以将缓存重写为接口的实现,这样可以更轻松地为示例中没有的某些位设置单元测试;我可以创建一个测试缓存对象,以我需要的任何方式提供我的价格历史记录,而无需访问数据库。

问题是当 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)]

同样,如果我只对 PriceCache 使用静态方法,那么基本代码和缓存工作正常,我将其创建为单例 "manually"。将它转换为让 Spring 处理其他地方的创建和注入也很好。只有当我混合使用 Hibernate 和 Spring 时,我 运行 才遇到问题。

我还没有尝试过使用外部 XML 文件作为休眠配置,这可能会解决问题,也可能不会。

有没有办法告诉 Hibernate 这是不是列?或者我应该遵循不同的模式来做这种事情,也许是 Item 对象的某种代理?

您可以使用 @Transient 注释,表明它不应持久保存到数据库中。

一般来说,我认为如果这是一个实体,它不应该有任何不属于它的自动装配缓存,但那是另一回事

关于下面答案中的讨论。 Hibernate 集合和实体都是代理对象。 也许您可以尝试实现一个自定义的 HibernateProxy 来管理您的集合。 根据文档,这似乎是可能的(CustomProxies),但我从来没有做过这里检查:https://docs.jboss.org/hibernate/orm/5.4/userguide/html_single/Hibernate_User_Guide.html#entity-proxy