Загрузка динамически созданного объекта с помощью автоматического обнаружения - PullRequest
0 голосов
/ 23 сентября 2011

Мне приходится работать со странной структурой БД, где на производстве может быть больше таблиц, но с такими же столбцами.И мы хотим использовать JPA (Hibernate) с их обработкой, посредством сущностей / JPQL-запросов.Идея состоит в том, чтобы динамически создавать классы сущностей для каждой таблицы в JVM во время выполнения.Этот подход работает отлично.Я создаю сущности с помощью Javassist - используя уже существующую скомпилированную сущность и динамически добавляю к ней аннотации (Entity, Table):

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 из объекта Configuration, добавляяэто классы, использующие метод addAnnotatedClass для конфигурации, он работает нормально.Проблема заключается в автоматическом обнаружении, поскольку сущность не обнаруживается / не обнаруживается ни JPA, ни AnnotationSessionFactoryBean - когда я использую сканирование пакетов в контексте Spring.(Я получаю: "QuerySyntaxException: [MyEntity] не сопоставлено" исключение)

Class.forName (myNewEntityName) работает, что означает, что он инициализируется в Classloader.

(Конечно, я знаю, что это не идеальный шаблон для обработки этих таблиц.)

Вопрос в том, почему и как его исключить?

(Javassist 3.15.0-GA, hibernate-ядро 3.6.6. Final, hibernate-entitymanager 3.5.6-Final)

1 Ответ

2 голосов
/ 24 сентября 2011

Я думаю, что сканирование пакетов происходит в банках и папках в classpath, а не на уровне загрузчика классов. Это оптимизирует загрузку не всех классов в память. Эта статья содержит некоторые подробности того, как это делается.

Чтобы решить эту проблему, вам, возможно, придется расширить AnnotationSessionFactoryBean - и динамически добавить список классов.

...