简体   繁体   English

Hibernate和Spring事务-使用私有构造函数/静态工厂方法

[英]Hibernate and Spring transactions - using private constructors/static factory methods

We have a Hibernate/Spring application that have the following Spring beans: 我们有一个Hibernate / Spring应用程序,它具有以下Spring Bean:

<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager" />
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean" />

When wiring the application together we get the following error when using private constructors in our hibernate entities: 将应用程序连接在一起时,在休眠实体中使用私有构造函数时,会出现以下错误:

Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: No visible constructors in class 'ourclass'

The entities are typical domain objects such as an Employee or the like. 实体是典型的域对象,例如Employee等。

When changing the constructor's visibility modifier to package (or public) the application runs fine and the entities gets stored/loaded in the database. 当将构造函数的可见性修改器更改为打包(或公共)时,应用程序运行良好,并且实体存储/加载到数据库中。 How do we/can we use private constructors/static factory methods with Spring/Hibernate transaction management? 我们/如何在Spring / Hibernate事务管理中使用私有构造函数/静态工厂方法?

We use Hibernate annotations to map the entities/relationships. 我们使用Hibernate注释来映射实体/关系。 No bean definitions are declared in the applicationContext.xml for the domain class that is related to the problem. 在applicationContext.xml中没有为与该问题相关的域类声明任何Bean定义。 It is a pojo that should have a static factory method and a private constructor. 这是一个pojo,应该具有静态工厂方法和私有构造函数。

How can we make Hibernate (org.springframework.spring-orm.hibernate3 classes i guess) make use of the static factory method instead of the constructor? 我们如何才能使Hibernate(我猜是org.springframework.spring-orm.hibernate3类)使用静态工厂方法而不是构造函数? Or possibly make it call a private constructor if necessary? 还是可以在必要时将其称为私有构造函数?

Using the spring factory-method configuration would make sense but the entities are not mapped as beans in our applicationContext.xml. 使用spring工厂方法配置是有意义的,但是在我们的applicationContext.xml中,实体未映射为bean。 They are only annotated with the @Entity annotation for Hibernate persistence. 它们仅使用@Entity注释进行注释,以实现Hibernate持久性。

Hope this edit clearifies (rather than mystifies) the question. 希望此编辑能够解决(而不是使问题迷惑)这个问题。 :) :)

While I haven't used Spring, I have used Hibernate in a project which has classes which must either be instantiated by factory methods or through multiple argument constructors. 虽然我没有使用过Spring,但我在一个项目中使用了Hibernate,该项目具有必须通过工厂方法或通过多个参数构造函数实例化的类。

You can do this through an Interceptor, which is a class which listens in to several key hibernate events, such as when an object needs to be instantiated or when an object is loaded. 您可以通过Interceptor进行此操作,Interceptor是侦听几个关键的休眠事件的类,例如何时需要实例化对象或何时加载对象。

To make Hibernate use your own means of instantiating the object, do something like this: 要使Hibernate使用您自己的实例化对象的方法,请执行以下操作:

public class MyInterceptor extends EmptyInterceptor {

    public Object instantiate(String entityName, EntityMode entityMode, Serializable id) {
        if(entityName.equals(Foo.class.getName())
             return Foo.create();
        return null;
    }
}

I'm a little suprised that you are having issues with Hibernate not instantiating objects with a non visible constructor, considering that it can be worked around with reflection and I haven't had that issue in my project (non of the classes actually have visible constructors). 令我有些惊讶的是,您遇到了Hibernate无法使用非可见构造函数实例化对象的问题,考虑到它可以通过反射解决,而我的项目中没有这个问题(实际上所有类都不具有可见性)构造函数)。 It may be something with Spring. 可能与Spring有关。 Check which version of hibernate you are using as well. 检查一下您正在使用的休眠版本。

Do you know about the property "factory-method" ? 您是否知道“工厂方法”属性? You can make spring call that method instead of the constructor to instantiate a bean. 您可以使spring调用该方法而不是构造函数来实例化bean。

I don't think you can make Hibernate (or any external framework) call a private constructor on your objects, unless it's through some javassist or cglib runtime created subclass. 我认为您不能让Hibernate(或任何外部框架)在对象上调用私有构造函数,除非它是通过某些javassist或cglib运行时创建的子类来实现的。

If you want to let Hibernate call your constructor, why don't you just make it public , or package ? 如果要让Hibernate调用构造函数,为什么不只是将其publicpackage呢? Hibernate instantiates your objects by calling the default no-argument constructor. Hibernate通过调用默认的无参数构造函数实例化您的对象。 The documentation states your classes must have the default no-arg constructor with package or public visibility. 文档指出您的类必须具有带有包或公共可见性的默认no-arg构造函数。 Your classes must not be final because Hibernate creates proxies for them when using associations. 您的课程不得为final课程,因为Hibernate在使用关联时会为其创建代理。

Section 3.2.3.2 of the Spring Reference discusses the few different ways of instantiating beans in Spring. Spring Reference的3.2.3.2节讨论了在Spring中实例化bean的几种不同方法。

You're either interested in the static factory or instance factory methods. 您对静态工厂或实例工厂方法感兴趣。 All sub sections are pretty short. 所有子节都很短。 Take a look and see if you have any further questions. 看看是否还有其他问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM