我们有一个Hibernate / Spring应用程序,它有以下Spring bean:
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager" />
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean" />
在将应用程序连接在一起时,在我们的hibernate实体中使用私有构造函数时会出现以下错误:
Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: No visible constructors in class 'ourclass'
实体是典型的域对象,例如Employee等。
将构造函数的可见性修饰符更改为包(或公共)时,应用程序运行正常,实体将存储/加载到数据库中。我们如何/可以在Spring / Hibernate事务管理中使用私有构造函数/静态工厂方法?
我们使用Hibernate注释来映射实体/关系。 applicationContext.xml中没有为与该问题相关的域类声明bean定义。它是一个pojo,应该有一个静态工厂方法和一个私有构造函数。
我们怎样才能使Hibernate(org.springframework.spring-orm.hibernate3类)使用静态工厂方法而不是构造函数?或者可能在必要时让它调用私有构造函数?
使用spring factory-method配置是有意义的,但实体不会在applicationContext.xml中映射为bean。它们仅使用Hibernate持久性的@Entity注释进行注释。
希望这个编辑能够澄清(而不是神秘)这个问题。 :)
答案 0 :(得分:5)
虽然我没有使用Spring,但我在一个项目中使用了Hibernate,该项目的类必须通过工厂方法或多个参数构造函数实例化。
您可以通过Interceptor执行此操作,Interceptor是一个侦听多个关键hibernate事件的类,例如当对象需要实例化或者加载对象时。
要使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;
}
}
我对Hibernate没有使用不可见的构造函数实例化对象的问题感到有点惊讶,考虑到它可以通过反射解决,我在我的项目中没有遇到过这个问题(非类的)实际上有可见的构造函数)。它可能与Spring有关。检查您正在使用的休眠版本。
答案 1 :(得分:1)
你知道属性“工厂方法”吗?你可以使用spring方法而不是构造函数来实例化bean。
答案 2 :(得分:0)
我认为您不能让Hibernate(或任何外部框架)在您的对象上调用私有构造函数,除非它是通过某些javassist或cglib运行时创建的子类。
如果你想让Hibernate调用你的构造函数,为什么不把它作为public
或package
呢? Hibernate通过调用默认的无参数构造函数来实例化您的对象。该文档声明您的类必须具有包含或公共可见性的默认no-arg构造函数。您的类不能是final
,因为Hibernate在使用关联时会为它们创建代理。
答案 3 :(得分:0)
Section 3.2.3.2 of the Spring Reference讨论了在Spring中实例化bean的几种不同方法。
您对静态工厂或实例工厂方法感兴趣。所有子部分都很短。看看你是否还有其他问题。