0

私は奇妙なDB構造で作業する必要があります。本番環境では、同じ列を持つより多くのテーブルが存在する可能性があります。そして、エンティティ/JPQL クエリによって、それらを処理する JPA (Hibernate) を使用したいと考えています。アイデアは、実行時に 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();
  }

Configuration オブジェクトから手動で Hibernate SessionFactory を構築し、addAnnotatedClass メソッドを使用してこのクラスを Configuration に追加すると、正常に動作します。問題は自動検出にあり、エンティティはJPAでもAnnotationSessionFactoryBeanでも検出/検出されません-Springコンテキスト内でパッケージスキャンを使用すると。(私は取得:「QuerySyntaxException: [MyEntity] がマップされていません」例外)

Class.forName(myNewEntityName) は機能します。つまり、クラスローダー内で初期化されます。

(もちろん、これがこれらのテーブルを処理するための理想的な設計パターンではないことはわかっています。)

問題は、なぜ、どのようにそれをソール化するのかということです。

(Javassist 3.15.0-GA、hibernate コア 3.6.6.Final、hibernate-entitymanager 3.5.6-Final)

4

1 に答える 1

2

パッケージのスキャンは、クラスローダー レベルではなく、クラスパス内の jar とフォルダーで行われると思います。これは、すべてのクラスをメモリにロードしないように最適化するためです。この記事には、それがどのように行われるかの詳細が記載されています。

それを解決するには、 AnnotationSessionFactoryBean を拡張し、クラスのリストを動的に追加する必要がある場合があります。

于 2011-09-24T04:13:56.407 に答える