2014-03-13 54 views
0

我有一个数据库有3个表。主表是Contract,它与来自两个表的键对配对:LanguagesRegions。 每一对都是独一无二的,但它是可能的一个合约将有以下对IDS:休眠三表很多很多

{ (1,1), (1,2), (2,1), (2,2) } 

今天,三个表经由连接实体链接称为ContractLanguages。它包含一个序列ID,以及来自三个表的id的三元组。 但是,在足够大的合同中,这会导致严重的性能问题,因为休眠环境会产生数量惊人的对象。 因此,我们想删除这个连接实体,以便合约将保存这些对的一些集合。

我们建议的解决方案:创建一个包含Language和Region id的@embeddable类,并将它们存储在Contract实体中。 这个背后的想法是,有相对少数的语言和地区。 我们假设hibernate管理这些对的列表并且不会创建重复项,因此大大减少了创建的对象的数量。

但是,我们有以下问题:

  1. 请问这个解决方案的工作?冬眠会知道创建正确的对象吗?
  2. 假设解决方案有效(链接已正确创建),hibernate会优化对象创建以停止创建重复对象吗?
  3. 如果此解决方案不起作用,我们如何解决上述问题而无需连接实体?
+0

是否可以保持连接实体,但采用延迟加载?如果我正确地理解你,每个合同可能只有有限数量的这种连接实体 - 你在使用时是否需要这些实体?多个合同?除此之外,您可以使用查询来仅从连接表中加载id(例如'SELECT connection.region.id,connection.language.id,... FROM ContractLanguages connection ...')并手动创建对象需要。 – Thomas

+0

看看我的网站上的帖子,也许它会很有用:http://itmuslim.org/blog/2014-03-13-629 – DmitryKanunnikoff

+0

@Thomas我确实需要他们,因为我在我的系统中持有很多合同一次,他们每个人可以有完全相同的对,所以我试图实现的是只持有一对实体,所有的合同都会有一套对这个实体的引用。我不确定我是否理解你的第二个建议,请你详细介绍一下。 – DiSol

回答

0

从您的文章和评论我假设以下情况,请纠正我,如果我错了:

  • 你有一组有限的Languages + Regions组合(目前建模为ContractLanguages实体)
  • 你有一个巨大的Contract实体
  • 量每手合约可以引用多个LanguagesRegions
  • 你必须加载所有合同语言问题,因为目前的组合是由合同+语言+基于这些假设区域

的,有几个可能的优化来我的脑海:

  • 您可以创建一个LanguageRegion实体,它具有唯一的id,每个合约引用一组这些实体。这样你会得到更多的表,但是Hibernate只会根据LanguageRegion创建一个实体,并在每个会话中加载一次,即使多个合约都会引用它。为了正常工作,您应该使用延迟加载,并可能在加载合同之前将这些实体加载到第一级缓存中。

  • 或者,您可以只加载所需的列,即只加载实体的一部分。您也可以使用延迟加载,但不会直接访问合约语言,而是在单独的查询中加载它们,例如(名猜)

    SELECT c.id, lang.id, lang.name, region.id, region.name FROM Contract c 
    JOIN c.contractlangues cl 
    JOIN cl.language lang 
    JOIN cl.region region 
    WHERE c.id in (:contractIds) 
    

    然后你载入合同,获得它们的ID,使用查询负载的语言和区域具体情况选择(它返回一个包含列值的对象数组List<Object[]>。你把那些到一个合适的数据结构,并根据需要访问它们。这样,你会分流实体的创建和刚刚获得所需要的数据。

+0

您的假设是正确的,我们已经开始实施我们的@embeddable想法,看看它是否会像我们预期的那样工作(实际上它为每个可能的配对创建一个且只有一个实体,并且我们期望所有合约lang + reg集合都能成立参考相同的实体),但如果它不起作用,我们会按照我们的计划进行操作,而这正是您在第一点中所写的内容(我们尽可能避免数据库更改)。关于第二个解决方案,我不确定我明白这个后续查询应该放在哪里?它是否在hibernate表def之外? – DiSol