4

私は現在、アプリケーションでエンティティマネージャーとユーザートランザクションを取得するための最良の方法を見つけようとしています。

JBoss 5.1では、JBSファイルに直接挿入することができましたが、これはもう許可されていません。

<%!@PersistenceContext(unitName = "unitname")
    public EntityManager em;

    @Resource
    UserTransaction utx;
%>

サーブレットやコントローラクラスなど、アプリケーション内のさまざまな場所からアクセスする必要がemあります。utxですから、一箇所にまとめてグローバルにアクセスできればいいのですが、どうすればいいのかまだわかりませんでした。ヒントをいただければ幸いです。

4

4 に答える 4

4

サーブレット、コントローラクラス、JSPファイルでEntityManagerとUserTransactionを取得する方法を見つけました。

SessionBeansから始めましょう。すべてのコントローラークラスをステートレスSessionBeansとして再定義しました。セッションBeanは、リソースインジェクションを許可します。これは私がそれをした方法です:

@Stateless
public class UserHandling {
  @PersistenceContext(unitName = "SSIS2")
  private static EntityManager em;

  @Resource
  private UserTransaction utx;

  public User getUser(int userId) {
    User userObject = em.find(User.class, userId);
    return userObject;
  }
}

セッションBeanクラスで別のセッションBeanが必要な場合は、@EJBアノテーションを挿入できます。

@Stateless
public class UserHandling {
  @PersistenceContext(unitName = "SSIS2")
  private static EntityManager em;

  @Resource
  private UserTransaction utx;

  @EJB
  UserHandling uh; RoleHandling rh; 

  public User getUser(int userId) {
    User userObject = em.find(User.class, userId);
    return userObject;
  }
}

JSPファイルでは、InitialContextをルックアップすることでSessionBeanControllerクラスを取得できます。

<%
    InitialContext ic = new InitialContext();
    UserHandling uh = (UserHandling) ic.lookup("java:app/" + application.getContextPath() + "/UserHandling");
%>
于 2012-08-07T09:13:53.073 に答える
4

解決中の問題

サーブレットとJSPは複数のスレッドで共有されるため、ステートレスである必要があります。は状態を保持するEntityManagerため、単一のインスタンスを並行スレッドで共有することはできません。

EntityManagerを取得するためのスムーズでシームレスなメカニズムが必要です。できればサーブレットコンテナによって管理されます。

サーブレット-コンテナ管理による永続性コンテキスト

ContainerManagedPersistenceContextサーブレット/JSPランタイムにを導入しましょう。

すぐに定義します。EntityManagerまず、これを使用してに注入する方法を見てみましょうJSP

<%! @Inject
    @ContainerManagedPersistenceContext.Qualifier
    public EntityManager em;
%>

または、さらに良いのはコントローラーに(データ回復/ビジネスロジックをJSPから分離したいからですよね?):

@Named
@SessionScoped
public class SessionController implements Serializable
{
    ...

    @Inject
    @ContainerManagedPersistenceContext.Qualifier
    private EntityManager em;
}

しかし、私は(まだ)CDIを利用できません

CDIはないが、JSFはある場合は、コンテキストを古いスタイルの標準JSFとして挿入できます@ManagedProperty

@Named
@SessionScoped
public class SessionController implements Serializable
{
    ...

    @ManagedProperty(value = "#{containerManagedPersistenceContext}")
    ContainerManagedPersistenceContext cmpContext;

    ...
    public void myMethod() {
        EntityManager em = cmpContext.getEntityManager();
       try {
            ...
        } finally {
            em.close();
        }
    }
}

そもそもこの取り組みにEntityManager取り組まなければならないのと同じ理由で、決してどこにもキャッシュ/保存してはならないことを忘れないでください。

トランザクション

EntityTransactionによって提供されるEntityManagerbegin/commit/rollbackを使用します。

EntityTransactionトランザクション=em.getTransaction();

ContainerManagedPersistenceContext

これは、アプリケーションスコープのコントローラーおよびPersistenceContext:として定義されます。

@PersistenceContext(name = ContainerManagedPersistenceContext.NAME,
                    unitName = ContainerManagedPersistenceContext.UNIT_NAME)
@ApplicationScoped
public class ContainerManagedPersistenceContext implements Serializable
{
    private static final long serialVersionUID = 1L;

    // UNITNAME must match persistence.xml: <persistence-unit name="myUnitName">
    public static final String UNITNAME = "myUnitName";
    public static final String NAME = "persistence/" + UNIT_NAME;


    @Qualifier
    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.METHOD, ElementType.FIELD,
             ElementType.PARAMETER, ElementType.TYPE})
    public static @interface Qualifier { }

    // Servlets must be stateless (shared across multiple threads).
    // EntityManager is not stateless (cannot be shared across threads).
    // Obtain Container Managed EntityManager - and do NOT cache.
    @Produces @Qualifier
    public static EntityManager getEntityManager() throws NamingException
    {
        EntityManager lookup = InitialContext.doLookup("java:comp/env/" + NAME);
        return lookup;
    }
}

制限事項

記述されているように、これはサーブレットコンテナ用に特別に名前が付けられたPersistenceContextを定義します。はunitNameパラメータ化されていないため、次のようなレベルの柔軟性は提供されません。

@PersistenceContext(unitName = "unitname")
public EntityManager em;

代替案

サーブレットでPersistenceContextを定義し、JNDI名ルックアップを使用します

于 2012-08-12T00:11:07.717 に答える
1

さて、私はあなたが別の観点から問題を見るべきだと思いますか?なぜEJBfromJSPページを呼び出す必要があるのですか?

JSPページにコードを含めることはできず、プレゼンテーションにのみ使用されます。Servletaまたはaを追加しJSF frameworkServletまたはManagedBeanを呼び出しEJBてから、パラメーターをに渡すことをお勧めしますJSP

お役に立てば幸いです

于 2012-08-08T14:34:05.120 に答える
-1

次のスニペットを使用して、JNDIルックアップを介してEntityManagerやUserTransactionを取得できます。

try {
   Context ic = (Context) new InitialContext();
   EntityManager em = (EntityManager) ic.lookup("java:comp/env/*<persistence-context-name>*");
   UserTransaction ut = (UserTransaction) ic.lookup("java:comp/env/UserTransaction");
} catch (NamingException ne) {...}
于 2012-08-02T09:00:57.987 に答える