1

エンティティがエンティティ マネージャにアクセスできるようにするこの設計を評価しています。

書籍の実体:

@Entity
public class Book implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private Long isbn;
    private String nom;

     public void save() {
        System.out.println("OWN PERSIST !");
      **ThreadLocalEntityManager.em().persist(this);**
    }
}

ブックサービス:

@Stateless
@Interceptors(EntityManagerInjector.class)

public class BookService {
       public void create()
       {
         Book b=new Book(1,2,"3");
         b.save();
       }
}

EntityManagerInjector

public class EntityManagerInjector implements Serializable {

    @PersistenceContext
    private EntityManager em;

    @AroundInvoke
    public Object associate(InvocationContext ic) throws Exception {
        ThreadLocalEntityManager.associateWithThread(em); //statically imported method
        try {
            return ic.proceed();
        } finally {
            ThreadLocalEntityManager.cleanupThread();
        }
    }
}

ThreadLocalEntityManager

public class ThreadLocalEntityManager {

    private static final ThreadLocal<EntityManager> THREAD_WITH_EM = new ThreadLocal<EntityManager>();

    private ThreadLocalEntityManager() {
    }

    public static void associateWithThread(EntityManager em) {
        THREAD_WITH_EM.set(em);
    }

    public static EntityManager em() {
        System.out.println("gettint entitymanger from thread:"+THREAD_WITH_EM.toString());
        System.out.println("entitymanger id:"+THREAD_WITH_EM.get().toString());
        return THREAD_WITH_EM.get();
    }

    public static void cleanupThread() {
        THREAD_WITH_EM.remove();
    }
}

いくつか質問があります:

  1. これは、crud サービス (create、delete、findXX) を使用しないようにするための適切な設計ですか?
  2. この設計により、コンテナ内で何らかの種類のランタイム実行の問題が発生する可能性がありますか?
  3. 宣言を static に変更することはbook.save()、「永続化操作」へのアクセスを簡素化する良い方法です (new を避けBook().find(id)"ますか?

ありがとう 。ps1:と Glassfish 3.1.2を使用JPA 2していますEjb 3.1

ps2: この設計は Real World Java EE Patterns Rethinking Best Practices (Adam Bien) で見つけました。

4

1 に答える 1

4

私はこのデザインに異議を唱えます。

  1. スレッドをいじると、ほとんどのアプリサーバーはそれを好まない

    App Server は、リクエストを処理するために多くのほぼ魔法のスレッド管理を行うため、JavaEE でスレッドを作成しないことを強くお勧めします。

  2. EntityManagers は一時的なものです

    EM は、実際には、トランザクションが存続している間だけ存続する必要があります。この例では、同じコンテナーで実行されている別のアプリケーションに EM を渡すことができるようです。これにより、デバッグが本当に楽しくなります。

    BookService から別の EJB を呼び出すと、EM が他の EJB の EM に設定されると想像してください。永続化ユニットが 2 つある場合、これは大きな問題になります。

  3. 延長不可

    このシステムの新しい EJB は、EM を処理するこの興味深い方法について知っている必要があります。あなたがそれらを書いているのであればこれは問題ありませんが、外部から提供された EJB はどうでしょうか?

  4. 結束の欠如

    EJB は、トランザクションが制御/定義される場所です。JPA Bean にインターフェースをプッシュする必要があるのはなぜですか? save()この非常に特殊なフレームワーク内でのみ機能し、単体テストのお尻に 100% の苦痛を与えることになります。

    WebServices のような XML シリアライゼーションを必要とする何かを行うために、この Bean を再利用するかどうかを考えてみてください。今save()は正しく動作しません。永続化エンジンはすでに一般的に Bean を処理できます。その上に別のレイヤーを記述して削除しないでください。

于 2012-12-28T01:34:27.320 に答える