我开发了一个库,在抽象类中给定某些注释,在运行时生成抽象类的特殊类。 所以我的库有点像:
X x = newInstance(X.class) //X is an abstract class
此库使用Javassist在运行时生成子类,该子类将由newInstance
方法实例化。
据我所知,Hibernate还使用Javassist来在运行时实体类中进行检测(如果不是这样,请有人纠正我。)
我的问题是,是否可以使两个框架协同工作?我的意思是,我可以告诉Hibernate每次它需要一个实体类(抽象类)的实例时,它应该使用我库中的特定工厂方法吗?
我不知道Hibernate是否在courtains后面工作,也是在实体类的运行时生成子类(假设Hibernate也需要对它们进行检测)。如果是这种情况,传递给Hibernate的解决方案某些类的工厂将无法工作。 在这种情况下,Hibernate是否对使用抽象实体类有任何支持?我的意思是,应该可以使用抽象(或接口?)实体类,并以某种方式告诉Hibernate,当需要使用这些抽象实体类中的一个时,它应该是正确的具体类。
但另一个复杂因素是在编译时不存在特定抽象实体类的具体类。
答案 0 :(得分:4)
在前往你的asnwer之前:
可悲的是,我认为您无法将Hibernate配置为使用自己的工厂。有关详细信息,我邀请您阅读长答案部分。
据我所知,目前,Hibernate 4.x仅支持Javassist作为其字节码操作提供程序。虽然,它曾经允许您在3.x版本中切换GClib和Javassist。回到这些版本,您可以通过配置名为hibernate.bytecode.provider
的hibernate全局设置来修改要使用的工厂。
此设置不再显示在Hibernate 4.1 documentation中,但您仍可在optional configuration properties下的Hibernate 3.2文档中找到相关内容。
作为自己的开发人员,我知道有时候我们是一些棘手的人,只是因为某些东西不在文档中并不一定意味着它不在代码中:-)所以,我虽然也许如果设置仍然存在,我们可以尝试利用它来做你想做的事情(尽管以不支持的方式)。
为了好奇,因为我在我的机器上使用了Hibernate 4.0.1代码(虽然不是最新的代码)但我做了一些挖掘...而且很惊讶,这个属性仍然存在!在跟踪使用过的引用之后(谢谢Eclipse)我最后在类org.hibernate.cfg.Environment(code for version 4.2.0.CR2)中找到了以下代码(代码在我的版本和4.2.0CR2中都是相同的) :
public static BytecodeProvider buildBytecodeProvider(Properties properties) {
String provider = ConfigurationHelper.getString( BYTECODE_PROVIDER, properties, "javassist" );
LOG.bytecodeProvider( provider );
return buildBytecodeProvider( provider );
}
private static BytecodeProvider buildBytecodeProvider(String providerName) {
if ( "javassist".equals( providerName ) ) {
return new org.hibernate.bytecode.internal.javassist.BytecodeProviderImpl();
}
LOG.unknownBytecodeProvider( providerName );
return new org.hibernate.bytecode.internal.javassist.BytecodeProviderImpl();
}
所以到目前为止,我可以告诉它代理工厂的Javassist实现,并且没有标准的方法来更改它。
疯子旁注
我要说的是纯粹的疯狂并且它不应该被考虑在生产代码中,而只能在中实际工作/学术/让弯曲事物场景< / em>的。
&lt; Hammer Hacking&gt;
org.hibernate.bytecode.internal.javassist.BytecodeProviderImpl
合并操作。BytecodeProviderImpl
将它放在同一个包org.hibernate.bytecode.internal.javassist
中,最后将它放在类路径中的某个地方,类路由器会在jar中找到它之前(或者可能)使用自定义类加载器)那么你只是喜欢监听到Hibernate,你的框架以及恐慌的整个JVM尖叫,不知道该做什么,或者它可以工作......
&lt; / Hammer Hacking&gt;
无论如何,如果你有时间并愿意尝试,请告诉我它是否成功。
<强>更新强>
在评论部分讨论了一下后,我有了这个想法,使用自定义EntityPersister。因为我对此不太确定,所以我用Google搜索了一下,看看我是否能找到一些可以告诉我我在想的东西能起作用的东西。
甚至比发现我的直觉是否正确更好,我在Stackoverflow中发现了一个似乎pretty similar to yours的问题。可悲的是,那里没有接受的答案。
但是这个问题的第一个答案,给出了与我的想法相似的链接。引用Pascal Thivent:
自定义EntityPersister实现(您可以register for a particular entity during Hibernate initialization using a custom Configuration)
这个例子适用于Grails中的Hibernate,但它在普通Java中几乎相同:
public void registerCustomEntityPersister(Configuration configuration) {
final Iterator<PersistentClass> classesIterator = configuration.getClassMappings();
while (classesIterator.hasNext()) {
final PersistentClass persistentClass = classesIterator.next();
if (checkIfIsOneTheClassesThatMatters(persistentClass)) {
persistentClass.etEntityPersisterClass(CustomEntityPersister.class);
}
}
虽然这看起来很可行,但看起来工作太多了,因为实现EntityPersister看起来并不那么琐碎......太多了。您可以尝试扩展Hibernate使用的默认值(我实际上不知道是哪一个)并尝试覆盖getProxy()方法以返回一个已检测的类。
很抱歉,如果它仍然不是一个答案的地方,但遗憾的是我不是Hibernate专家,我只是开箱即用,我实际上因为javassist标签登陆了你的问题,发现它非常有趣。
我希望至少我能为您提供可以帮助您的信息。