一个类可以同时注释为@Repository 和@Entity 吗?

Posted

技术标签:

【中文标题】一个类可以同时注释为@Repository 和@Entity 吗?【英文标题】:Can a class be annotated as both @Repository and @Entity? 【发布时间】:2013-01-30 09:12:37 【问题描述】:

我对 Hibernate 很陌生。我无法理解这些简单的逻辑。我知道 Spring 使用 @Repository 来访问对象。此外,Hibernate 使用 @Entity 来表示映射到数据库表中的实体。我只是想知道一个类是否可以同时使用 @Repository 和 @Entity 注释,因为它们或多或少暗示相同。

【问题讨论】:

NO(这是最小评论长度) 听起来像 ActiveRecord ;) 听起来违反了单一职责原则。 @SpaceTrucker - 我猜它在 Ruby 中很受欢迎,因为它有混合和鸭子类型,所以它并没有真正弄乱实体界面。 【参考方案1】:

没有。

Hibernate 实体由 Hibernate ORM 框架管理,当您通过 get() 或 load() 访问它们时,它们(及其代理)由 hibernate 创建。它们具有与 Spring bean 完全不同(且复杂)的生命周期(它们可以附加/分离/代理/等待移除)

Spring 存储库是单例的,由 Spring 框架管理。通常,只要容器实例存在,它们就存在。新的 Hibernate 会话可能会打开和关闭,新的用户会话可能会参与然后过期,但仍然会有相同的存储库单例实例。

请参阅http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/objectstate.html#objectstate-overview 了解可能的休眠对象状态。

至于存储库实例 - 通常它们是无状态的,因为它们是服务。

RE:they more or less imply the same. 不,它们不一样。有an old joke

更换一个灯泡需要多少 C++ 程序员?你是 还在程序上思考。一个设计合理的灯泡对象 将从通用灯泡类继承更改方法,所以所有 你要做的就是发送一个灯泡更换消息。

但是优秀的OOP程序员不这么认为,根据single responsibility principle,对象应该有一个单一的理由来改变。存储库与基础设施一起工作,与业务规则无关。基础设施可能会发生变化(例如,您可能需要将对象存储在 XML 而不是 RDBMS 中),但这不应影响封装业务对象状态的类。

您可以通过从实体类引用抽象存储库接口来缓解此问题(实现臭名昭著的Active Record 模式 - 这就像从灯泡中引用一些抽象灯泡插座,这似乎不是一个很好的解决方案,因为灯泡插座和灯泡具有不同的生命周期)。

这就是High Cohesion原则开始发挥作用的地方,根据该原则,对于一个对象来说,它的作用是反映模型的抽象,执行一些完全不相关的事情,比如持久性或通过网络传输,这是不合逻辑的。当Student 类有print()saveToXml()transmitByHttp() 方法时,这很奇怪。

【讨论】:

【参考方案2】:

它们根本不暗示同样的事情。

@Entity

@Entity 是代表您业务领域中的“事物”的事物。它可以是任何东西——客户、大象、产品。 . .它将具有将持久保存到数据库的属性以及与这些属性相关的方法(至少它应该,除非它是一个贫血实体,但这是一种反模式......稍后,当你对基础知识请查看 Spring 的 @Configurable 注解——这允许您为您的实体提供协作者)。

@Repository

另一方面,@Repository 提供了一个用于检索和存储这些实体的接口。

有一些框架,特别是在其他语言中,将持久性和实体属性结合在同一个对象上,但是这在 Java/Hibernate/Spring 中并不常见。

【讨论】:

另一个答案有很多很好的信息,但这更简洁明了,所以它得到了我的投票。

以上是关于一个类可以同时注释为@Repository 和@Entity 吗?的主要内容,如果未能解决你的问题,请参考以下文章

Spring @Repository 注释不起作用,但 @Service 注释起作用?

@Repository@Service@Controller 和 @Component

@Repository@Service@Controller 和 @Component

@Repository@Service@Controller 和 @Component

visual studio 中如何对多行代码同时打上“//”或者同时删除注释符?求VS中的各种快

@Repository 注释的真正目的[重复]