2011-09-23 63 views
0

我必须使用奇怪的数据库结构,在生产时可能会有更多的表,但具有相同的列。我们希望使用JPA(Hibernate)来处理它们,通过实体/ JPQL查询。这个想法是在运行时在JVM中动态地为每个表创建实体类。这种方法工作正常。我创建实体用Javassist - 使用已经存在的编译的实体,我添加注释它动态地(实体,表):通过自动恢复加载动态创建的实体

public Class generateGroupStateEntity(String className,String tableName) { 
    ClassPool cp = ClassPool.getDefault(); 
    InputStream is = new FileInputStream(new File("MyTemplateEntity.class")); 
    CtClass c = cp.makeClass(is); 
    c.setName(className); 
    ClassFile cf = c.getClassFile(); 
    ConstPool constPool = cf.getConstPool(); 


    AnnotationsAttribute annotAtr = new AnnotationsAttribute(constPool,AnnotationsAttribute.visibleTag); 
    Annotation annot = new Annotation("javax.persistence.Entity", constPool); 
    annotAtr.addAnnotation(annot); 

    Annotation annotTable = new Annotation("javax.persistence.Table", constPool); 
    annotTable.addMemberValue("name", new StringMemberValue(tableName,cf.getConstPool())); 
    annotAtr.addAnnotation(annotTable); 

    cf.addAttribute(annotAtr); 
    return c.toClass(); 
    } 

当我建立一个Hibernate SessionFactory的手,从配置对象,添加该班使用addAnnotatedClass方法来配置,它工作正常。问题在于自动发现,实体不会被JPA或AnnotationSessionFactoryBean发现/发现 - 当我在spring上下文中使用包扫描时。 (我得到:“QuerySyntaxException:[MyEntity]未映射”异常)

Class.forName(myNewEntityName)作品表示它在Classloader中初始化。

(当然,我知道这是不是为处理这些表是一种理想的设计模式。)

的问题是,为什么和如何唯一呢?

(Javassist是3.15.0-GA,休眠核心3.6.6.Final,休眠-的EntityManager 3.5.6决赛)

+0

我的第一个虽然是可能有类加载器的问题,它被加载? – csviri

回答

2

我想包扫描发生在在classpath中罐子和文件夹 - 而不是在类加载器级别。这是为了优化不将所有类加载到内存中。这article有一些如何完成的细节。

要解决这个问题,您可能需要扩展AnnotationSessionFactoryBean - 并动态添加类的列表。

+0

是的,我已经实现了一个动态类添加,我会检查在春季扫描的实施,但可能这是问题。谢谢 – csviri