简体   繁体   English

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

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

I have a table which contains item descriptions.我有一个包含项目描述的表格。 Items have a price history which can be very extensive.物品的价格历史可能非常广泛。 It's that last bit that leads me to avoid using a normal one-to-many Hibernate mapping with lazy loading.正是最后一点让我避免使用带有延迟加载的普通一对多 Hibernate 映射。 Think a price history like ticks on a stock exchange, lots of history.想想一个价格历史,比如证券交易所的报价,有很多历史。

So I have a cache which works well, it's all wired with Spring, the DAO is injected, the cache manages what needs to be queried vs what it already knows.所以我有一个运行良好的缓存,它全部与 Spring 连接,注入了 DAO,缓存管理需要查询的内容与它已经知道的内容。

So, the "natural" thing is to be able to ask an item about it's price history.因此,“自然”的事情是能够询问商品的价格历史记录。 Here's some code, which is a slimmed down version of the real thing:这是一些代码,它是真实事物的精简版:

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

My original version used all static methods with PriceCache;我的原始版本使用 PriceCache 的所有静态方法; I want to switch to using an injected bean in part because it will mean I can rewrite the cache as an implementation of an interface which makes it easier to set up unit tests for some bits that aren't in the example;我想切换到使用注入 bean 的部分原因是,这意味着我可以将缓存重写为接口的实现,这使得为示例中没有的某些位设置单元测试变得更加容易; I can create a test cache object that supplies my price history in whatever way I need to the test without ever going to the database.我可以创建一个测试缓存对象,以我需要的任何方式提供我的价格历史记录,而无需访问数据库。

The problem is that when Spring and Hibernate scan the packages, they seem to conflict over what to do with that @Autowired field;问题是当 Spring 和 Hibernate 扫描包时,它们似乎在如何处理 @Autowired 字段上发生冲突; I get the following with some formatting for readability);为了便于阅读,我得到了以下一些格式); dbEMF is my EntityManagerFactory: 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)]

Again, the basic code and cache work fine provided I use only static methods with the PriceCache, where I create it as a singleton "manually".同样,如果我只对 PriceCache 使用静态方法,则基本代码和缓存工作正常,我在其中“手动”将其创建为单例。 Converting it to let Spring handle the creating and injection elsewhere works just fine, too.将它转换为让 Spring 处理其他地方的创建和注入工作也很好。 It's only when I have this mix of Hibernate and Spring that I run into a problem.只有当我混合使用 Hibernate 和 Spring 时才会遇到问题。

I haven't tried going back to using an external XML file for the hibernate config which might solve the issue, or not.我还没有尝试过使用外部 XML 文件进行休眠配置,这可能会解决问题,或者不能。

Is there a way to tell Hibernate this is not a column?有没有办法告诉 Hibernate 这不是列? Or is there a different pattern I should be following to do this sort of thing, maybe some sort of proxy for the Item objects?或者我应该遵循不同的模式来做这种事情,也许是 Item 对象的某种代理?

you can use @Transient annotation, to indicate it should not be persisted into DB.您可以使用@Transient批注,指示不应将其持久化到数据库中。

Generally speaking, I think if this is an entity, it should not have any autowired cache which is not part of it, but that's a different story一般来说,我认为如果这是一个实体,它不应该有任何不属于它的自动装配缓存,但这是另一回事

Regarding the discussion in the answer below.关于下面答案中的讨论。 Hibernate collections and entities are all proxied objects. Hibernate 集合和实体都是代理对象。 Maybe what you can try is to implement a custom HibernateProxy that will manage your collection.也许您可以尝试实现一个自定义 HibernateProxy 来管理您的集合。 As per the docs it seems to be possible (CustomProxies) but I have never done it check here: https://docs.jboss.org/hibernate/orm/5.4/userguide/html_single/Hibernate_User_Guide.html#entity-proxy根据文档,它似乎是可能的(CustomProxies),但我从未在这里检查过: https : //docs.jboss.org/hibernate/orm/5.4/userguide/html_single/Hibernate_User_Guide.html#entity-proxy

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM