【问题标题】:Avoiding DAO Cross Access避免 DAO 交叉访问
【发布时间】:2014-03-06 20:13:20
【问题描述】:

我正在构建一个简单的 Spring + Hibernate 应用程序,我有以下模型:

 Link ( id, url, title )
 History ( link_id, report_time, number_of_likes )

在我的 Main 方法中,我有这样的东西:

    public static void main(String[] args) {

      ApplicationContext context =
                new ClassPathXmlApplicationContext(new String[] {"spring.xml"});
      ...

      ((LinkDao) context.getBean("linkDao")).updateAll(date);

      ...
    }

此应用每 30 分钟运行一次;进入 LINK 表并在 HISTORY 表中记录当时 Facebook 的点赞数。

现在的问题是我需要在 LinkDaoImpl 但我无法从 LinkDaoImpl 访问 HistoryDaoImpl,除非我将上下文传递给 LinkDaoImpl。另外,如果我包括:

 @OneToMany
 List<History> history

在 Link 模型中,Hibernate 创建了一个额外的 HISTORY_LINK 表,这是不必要的。

这样做的正确方法是什么?

【问题讨论】:

  • 我不明白为什么你的历史表被保存在一个只应该用于访问链接表数据的方法中,你能解释一下为什么会这样。你真的应该重新考虑那个设计。 LinkDaoImpl 保存的历史表隐藏了 LinkDaoImpl 的 updateAll 的副作用,而且这个函数做了不止一件事。
  • @MarquisBlount 嗯,LINK 表也有类似 NUMBER_OF_FB_LIKES 的字段,...我调用 updateAll 方法首先更新 LINK 表,但 我将相同的值存储在 HISTORY 表中带有时间戳,所以以后我可以生成图表...

标签: java spring hibernate dao


【解决方案1】:

您需要在@OneToMany 中添加mappedBy="link"。当您使用关系 @ManyToOne 时,映射默认使用 @JoinColumn,但在 @OneToMany 中您必须指定关系的所有者

【讨论】:

    【解决方案2】:

    听起来您需要将包含在 linkDao.updateAll 中的一些逻辑提取到服务类中。服务类可以完成跨模型工作,让您的 DAO 只修改它们应该修改的表。然后将两个 DAO 注入到您的服务类中。

    【讨论】:

      【解决方案3】:

      当您使用@O​​neToMany 注解时,Hibernate 将始终在实体关系之间创建一个新表,即使您看不到它的真正用途。

      因此,在这种情况下,您应该尝试使用@OneToOne 注解,或者直接接受 Hibernate 创建的新表。

      【讨论】:

      • 不,并非总是如此。如果添加@JoinColumn(name = "link_id"),它将映射关联到link_id 连接列。
      • 很好,感谢您的更正。所以根据你的建议,我认为最好使用@JoinColumn 注解,而不是尝试另一个关系映射。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-20
      • 2019-04-10
      • 1970-01-01
      • 2013-02-20
      • 1970-01-01
      • 2019-05-01
      相关资源
      最近更新 更多