我对休眠很陌生。我无法理解这些简单的逻辑。我知道 Spring 使用 @Repository 来访问对象。此外,Hibernate 使用 @Entity 来表示映射到数据库表中的实体。我只是想知道一个类是否可以同时使用@Repository 和@Entity 进行注释,因为它们或多或少暗示相同。
2 回答
不。
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.
不,它们不一样。有个老笑话
换一个灯泡需要多少 C++ 程序员?你还在程序上思考。正确设计的灯泡对象会从通用灯泡类继承更改方法,因此您所要做的就是发送一个灯泡更改消息。
但是优秀的 OOP 程序员不这么认为,根据单一职责原则,对象应该有一个单一的理由来改变。存储库与基础设施一起工作,与业务规则无关。基础设施可能会发生变化(例如,您可能需要将对象存储在 XML 而不是 RDBMS 中),但这不应影响封装业务对象状态的类。
您可以通过从实体类引用抽象存储库接口来缓解这个问题(实现一个臭名昭著的Active Record模式 - 这就像从灯泡中引用一些抽象灯泡插座,这似乎不是一个好的解决方案,因为灯泡插座和灯泡有不同的生命周期)。
这就是高内聚原则开始发挥作用的地方,根据该原则,对于一个对象来说,它的作用是反映模型的抽象,执行一些完全不相关的事情,比如持久性或通过网络传输,这是不合逻辑的。Student
当类有print()
,saveToXml()
或transmitByHttp()
方法时,这很奇怪。
它们根本不意味着同样的事情。
@实体
@Entity 是代表您的业务领域中的“事物”的事物。它可以是任何东西——客户、大象、产品。. . 它将具有将持久保存到数据库的属性以及与这些属性相关的方法(至少它应该,除非它是一个贫血实体,但这是一种反模式......稍后,当你对基础知识请查看 Spring 的 @Configurable 注解——这允许您为您的实体提供协作者)。
@Repository
另一方面,@Repository 提供了一个用于检索和存储这些实体的接口。
有一些框架,特别是在其他语言中,将持久性和实体属性结合在同一个对象上,但是这在 Java/Hibernate/Spring 中并不常见。