Hibernate搜索,实体和SQL VIEW

时间:2011-11-01 18:00:38

标签: sql hibernate view lucene hibernate-search

我有一个表,用于维护使用PostgreSQL 9.1销售的产品行(tbl_products)。还有其他几个表维护项目,评论等的评级。我们在Seam应用程序中使用JPA / Hibernate进行ORM,并正确连接相应的实体。为了更好地列出这些项目,我创建了一个SQL VIEWv_product_summary),它汇总了一些基本的产品数据(名称,描述,价格等)和来自的数据。其他表格(评论数量,平均评分等)。这提供了一个非常简洁的数据视图,我创建了一个相应的JPA实体对象,它提供对视图数据的只读访问。

对于在Product对象(tbl_products)或ProductSummaryv_product_summary)对象上运行JPQL查询,一切正常。但是,我们希望使用Hibernate Search和Lucene提供更丰富的搜索体验。但是,我们遇到的问题是如何使用Hibernate Search查询ProductSummary个对象?它们在创作时没有编入索引,因为它们从未真正“创造”过。它们是从v_product_summary VIEW获取的只读对象。索引条目仅在Product保存到数据库时创建,而不是ProductSummary,因为它永远不会保留。

我们的想法是我们应该能够:

  1. 将我们的Product对象保留到数据库
  2. 使用产品ID
  3. 立即查询相应的ProductSummary对象
  4. 手动更新ProductSummary对象
  5. 的Hibernate Search索引

    这可能吗?这甚至是个好主意吗?我可以看到,由于我们每次持久保存新产品时都会对ProductSummary对象执行查询,因此会产生性能影响。但是,产品没有大量添加到数据库中,所以我认为这不是一个大问题。

    我们真的想找到一种更好,更有效的方法来实现这一目标。有人可以提供任何提示或建议吗?如果我们手动更新搜索索引的路线,那是否可行?任何人都可以提供资源来解释我们如何将单个ProductSummary添加到索引中吗?

    非常感谢您提供的任何帮助。

3 个答案:

答案 0 :(得分:1)

如果我正确地理解了这个问题,那么你正在尝试保持一个对象并在那时对其进行索引,但是你正在处理两个独立的对象。

我发现自己总是在Hibernate中做一些kludgey事情,感觉它几乎要求你。是的,会产生性能影响,正如您所说,这可能不是什么大问题,因此可能值得进行分析。

我的一部分记得有一种方法可以在写入时刷新对象,并想知道是否有一种方法可以包装Product和ProductSummary并调整映射,以便您阅读部分并写入部分内容(波形指针)关于语法和映射)。或者创建一个面向Hibernate的对象,该对象具有只能分割并合并到两个对象中的只读字段。我不知道你的设计是否只允许使用Hibernate对象,这是我系统中常见的习惯用法。

如果你在这种情况下有很多物体,那么这两种方式都很有用,如果这是你用这种方式搜索的唯一物体,那么你的3个步骤看起来会更清晰。

至于手动添加对象的语法,我认为你在获取之后正在寻找这样的东西:

FullTextSession textSession = Search.getFullTextSession(session);
textSession.index(myProductSummary);

那就是你想要的吗?

答案 1 :(得分:1)

由于您使用的是postgresql,因此可以插入视图并使用规则将插入重定向到相应的表。

postgresql规则是一种在执行之前更改查询的方法。我在一个需要更改架构的应用程序中使用它,但要求旧的查询仍然可以工作一段时间。

您可以查看documentation about rules on insert queries on the postgresql site

由于您将插入并更新到视图,因此hibernate搜索将照常工作。

修改

更简单的策略。在ProductSummary上执行此操作时,您可以插入并更新Product,并告诉PostgreSQL忽略视图上的插入,更新和删除。

在数据库方面“

create RULE dontinsert AS ON insert to v_product_summary do instead nothing
create RULE dontupdate AS ON update to v_product_summary do instead nothing
create RULE dontdelete AS ON delete to v_product_summary do instead nothing

但是我想你需要修改一下,因为jdbc调用executeUpdate将返回0,而hibernate可能会发疯。

答案 2 :(得分:0)

从技术上讲,我认为这是可能的,但我认为使用像memcached这样的东西可以更好地解决你的整个效率困境,从而使性能不再成为一个问题,并且可能会增加代码可维护性,具体取决于你当前如何在语句中实现它水平。通过手动更新搜索索引,您的意思是数据库索引吗?这是不推荐的,我不确定它是否可行。为什么不在创作时将它们编入索引?