为什么休眠不需要参数构造函数?

2022-08-31 08:50:40

无参数构造函数是必需的(像 Hibernate 这样的工具使用此构造函数上的反射来实例化对象)。

我得到了这个手挥舞的答案,但有人可以进一步解释吗?谢谢


答案 1

休眠和通过反射创建对象的一般代码使用 Class<T>.newInstance() 来创建类的新实例。此方法需要一个公共的 no-arg 构造函数才能实例化对象。对于大多数用例,提供无参数构造函数不是问题。

有一些基于序列化的黑客可以解决没有无arg构造函数的问题,因为序列化使用jvm魔术来创建对象而无需调用构造函数。但并非所有 VM 都可用。例如,XStream 可以创建没有公共无参数构造函数的对象实例,但只能通过在所谓的“增强”模式下运行,该模式仅在某些 VM 上可用。Hibernate的设计人员肯定选择保持与所有VM的兼容性,因此避免了此类技巧,并使用官方支持的反射方法,需要无arg构造函数。Class<T>.newInstance()


答案 2

Erm,对不起大家,但是Hibernate并不要求你的类必须有一个无参数的构造函数。JPA 2.0 规范需要它,这对于 JPA 来说非常蹩脚。其他框架(如 JAXB)也需要它,这对于这些框架来说也非常蹩脚。

(实际上,JAXB应该允许实体工厂,但它坚持自己实例化这些工厂,要求它们有一个 - 猜猜是什么 - 无参数构造函数,这在我的书中与不允许工厂一样好;这是多么蹩脚!

但是Hibernate不需要这样的东西。

Hibernate支持拦截机制(参见文档中的“Interceptor”),它允许您使用它们所需的任何构造函数参数实例化对象。

基本上,你要做的是,当你设置休眠时,你向它传递一个实现接口的对象,然后休眠将在它需要你的对象的新实例时调用该接口的方法,所以你对该方法的实现可以以你喜欢的任何方式你的对象。org.hibernate.Interceptorinstantiate()new

我已经在一个项目中做到了这一点,它就像一个魅力。在这个项目中,我尽可能地通过JPA做事,我只在没有其他选择的情况下使用Hibernate功能,如拦截器。

Hibernate似乎对它有些不安全,因为在启动期间,它为我的每个实体类发出一条信息消息,告诉我和,但后来我通过拦截器实例化它们,它对此感到满意。INFO: HHH000182: No default (no-argument) constructor for classclass must be instantiated by Interceptor

对于除Hibernate以外的工具来说,要回答问题的“为什么”部分,答案是“绝对没有充分的理由”,这可以通过休眠拦截器的存在来证明。有许多工具可以支持一些类似的客户端对象实例化机制,但它们没有,因此它们自己创建对象,因此它们必须需要无参数构造函数。我很容易相信这种情况正在发生,因为这些工具的创建者认为自己是忍者系统程序员,他们创建了充满魔力的框架,供无知的应用程序程序员使用,他们(所以他们认为)永远不会在他们最疯狂的梦想中需要像...工厂模式。(好吧,我很想这么想。我实际上并不这么认为。我是在开玩笑。


推荐