0

EntityManagerリフレクションを使用してEJBを動的に取得したいと思います。私はこのコードを持っています:

    @Stateful
    @Local(ContextLocal.class)
    public class ContextBean implements ContextLocal {

    @PersistenceContext(unitName="00")
    private EntityManager emBeta;

    @PersistenceContext(unitName="01")
    private EntityManager emPretoria;

    private static Logger logger = Logger.getLogger(ContextBean.class);

    public ContextBean() {}

    @Override
    public void createAccount(String pseudo, char[] password, String email, TemperamentEnum temperament, Universe universe, int galaxie, int solarSystem, int position) throws PSQLException {

        // Récupération de l'EntityManager adequat en fonction de l'univers choisi
        EntityManager em = getEmFromUniverse(universe);

    }

    /**
     * retourne un EntityManager en fonction d'un univers donné
     * 
     * @param universe
     * 
     * @return EntityManager
     */
    private EntityManager getEmFromUniverse(Universe universe){

        EntityManager em = null;

        try {

            Field[] fields = Class.forName(getClass().getPackage() + "ContextBean").getDeclaredFields();

            for(Field field : fields){
                if(!field.getType().equals(EntityManager.class))
                    continue;
                if(field.getName().replaceFirst("^em", "").equalsIgnoreCase(universe.getName()))
                    return (EntityManager)field; // ERROR HERE
            }

        } catch (SecurityException e) {
            logger.log(Level.FATAL, e);
        } catch (ClassNotFoundException e) {
            logger.log(Level.FATAL, e);
        }

        return em;      
    }

}

キャストできませFieldEntityManager

フィールドからEntityManagerにキャストできません

どうすればオブジェクトにキャストできFieldますEntityManagerか?

編集 :

universeを実行することでオブジェクトの名前を取得でき、またはuniverse.getName()を取得します。betapretoria

ゲッターを使用して適切なEMを取得できることはわかっています。

if(universe.getName().equals("beta"))
   return emBeta;
else
   ...

ただし、EJB内のEMの数はおそらく増えるでしょう。したがって、リフレクションを使用すると、コードは遅くなります(ただし、登録時にユーザーごとに1回だけ使用されます)が、新しいEMを追加するときにコードを変更する必要はありません。だから私はゲッターを使いません。

私の場合、リフレクションを使用することの欠点はありますか?

EDIT2:

取得したEMのトランザクションの整合性が失われる可能性はありますか?

4

2 に答える 2

1

取得する必要があるフィールドを含むオブジェクトを提供する必要があります。

boolean isAccessible = field.isAccessible();
try {
    field.setAccessible(true);
    return field.get(this); // <-- pass object instance here
} finally {
    field.setAccessible(isAccessible);
}
于 2012-12-19T16:40:26.223 に答える
0

同じクラス階層にないため、Field を EntityManager にキャストすることはできません。あなたが本当にしたいことは、フィールドのEntityManagerを次のように取得することです:

field.setAccessible(true);
final EntityManager manager = (EntityManager) field.get(universe);

上記のコードはこれを行う方法を示していますが、このアプローチは強くお勧めしません。Context オブジェクトでゲッターを作成してその方法で返すことができるのに、なぜリフレクションを介して Entity Manager を取得する必要があるのでしょうか? リフレクションを使用しないことをお勧めする理由は、エンティティ Bean がアプリケーション コンテナーによってプロキシされることになり、リフレクションを使用しても期待どおりの結果が得られない可能性があるためです。

于 2012-12-19T16:39:47.753 に答える