1

私はJPAとJSFにまったく慣れていないので、質問に答えていただければ幸いです。私のアプリケーションは、JSF 2.0フレームワークを使用して構築されており、Glassfish 3以降、MySQLで実行されているJPA 2.0/EclipseLinkを使用しています。

データソースを使用して「loginPU」という永続ユニットを1つ設定しました。「jdbc/loginDataSource」「jdbc/loginDataSource」は「login1」(mysqlusertableで定義)を使用してMySQLに接続し、にのみアクセスできますcustomeruserおよびcustomerroles選択権限のみを持つテーブル。

GlassfishJDBCResourcesで他の2つのデータソース「jdbc/admin」と「jdbc/staff」を作成しましたが、どちらも異なる権限を持っています

ログイン/認証のシナリオは次のとおりです。

  1. フォームベースの認証(ユーザー名とパスワード)を使用したユーザーログイン
  2. 永続ユニット「loginPU」および「jdbc/loginDataSource」を使用してEntityManageFactoryを作成します
  3. ユーザーロールを取得するためのクエリを作成する
  4. ユーザーロールがadminの場合、「jdbc/admin」データソースを使用して接続します
  5. ユーザーロールがスタッフの場合、「jdbc/staff」データソースを使用して接続します

上記の項目2の私のコードは次のようになります。

Map properties = new HashMap(); 
properties.put(TRANSACTION_TYPE, "JTA");

// Configure the internal EclipseLink connection pool
properties.put(JDBC_DRIVER, "com.mysql.jdbc.Driver");
properties.put(JDBC_URL, "jdbc:mysql://localhost:3306/customer");
properties.put(JDBC_USER, "login1");
properties.put(JDBC_PASSWORD, "login1");
properties.put(JTA_DATASOURCE, "jdbc/loginDataSource");

EntityManageFactory emf = Persistence.createEntityManagerFactory("loginPU",properties);

EntityManagerFactoryをセッション属性に保持し、JpaControllerクラスで取得することもできます

//save into session
session.setAttribute("entityManagerFactory", emf);

//retrieved in JpaController
public EntityManagerFactory getEmf() {

        HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
        HttpSession s = request.getSession(true);
        try {
            emf = (EntityManagerFactory) s.getAttribute("entityManagerFactory");
        } catch(NullPointerException ne){
            System.out.println("EMF Exception: "+ne);
        }

        return emf;
    }

質問:4番または5番を達成するにはどうすればよいですか?それは可能ですか?どちらかのデータソースを「loginPU」永続性ユニットに割り当てることは可能ですか?loginPUとjdbc/loginDataSourceを使用して接続を確立し、jdbc / adminデータソースを使用して接続しましたが、他のエンティティにアクセスすると、エラーがスローされ、デフォルトでjdbc/loginDataSourceになります。

注:エンティティを管理するために、netbeansによって作成されたJpaControllerクラスとセッションBeanを使用しています。私のJpaControllerクラスは

@Resource private UserTransaction utx;
@PersistenceUnit private EntityManagerFactory emf;

私のセッションBeanはすべて@Statelessです。unitNameを使用して、unitNameを使用せずに@PersistenceContextを使用しようとしましたが、うまくいきませんでした。

@PersistenceContext
private EntityManager em;

役割に基づいた永続性ユニット名を使用してユーザーを接続することを期待して、persistence.xmlで複数の永続性ユニットを使用しようとしましたが、サーバーにデプロイするときにエラーが発生します。

アプリケーション管理の永続性コンテナー管理について読みました。私が達成しようとしているのは、アプリケーション管理を使用することだと思いますが、その方法がわかりません。

コンテナ管理の永続性を使用する場合、複数のデータソースを使用することは可能ですか?どんな提案でも大歓迎です。

よろしくお願いします。

[解決済み]

  1. まず、persistence.xmlを次のように定義しました。

    <persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
        <persistence-unit name="mdbAdminPU" >
            <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
            <jta-data-source>jdbc/login</jta-data-source>
            <exclude-unlisted-classes>false</exclude-unlisted-classes>
        </persistence-unit>
    </persistence>
    
  2. セッションBeanで@PersistenceUnitまたは@PersistenceContextを使用していません(Netbeansを使用しており、これらのBeanはエンティティクラスからJSFページを作成したときに作成されました)

  3. すべてのセッションBeanで、次のようになります。

    @Stateless
    public class UserFacade extends AbstractFacade<User> {
    
        @Override
        protected EntityManager getEntityManager() {
            HttpSession session = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(false);
            EntityManagerFactory emf = (EntityManagerFactory) session.getAttribute("entityManagerFactory");
            EntityManager em = emf.createEntityManager(); 
            return em;
        }
    
        public UserFacade() {
            super(User.class);
        }
    }
    
  4. 上記のログインシナリオ(5項目)は7になりました:

  1. フォームベースの認証(ユーザー名とパスワード)を使用したユーザーログイン
  2. 永続ユニット「loginPU」および「jdbc/loginDataSource」を使用してEntityManageFactoryを作成します
  3. ユーザーロールを取得するためのクエリを作成する
  4. ユーザーロールがadminの場合、「jdbc/admin」データソースを使用して接続します
  5. ユーザーロールがスタッフの場合、「jdbc/staff」データソースを使用して接続します

プラス

  1. emf.close();を使用して、項目2で作成されたEntityManagerFactoryを削除またはクリアします。
  2. HttpSessionの項目4または5のいずれかで作成された新しいEntityManagerFactoryを保持します
4

1 に答える 1

0

3 つの異なるログインが必要な場合は、persistence.xml で 3 つの個別の永続化ユニットを使用するのがおそらく最善です。または、フルアクセスで単一のログインを行い、アプリケーションでセキュリティを検証します (とにかく部分的に行っているようです)。

デプロイ時にどのようなエラーが発生しましたか?

これは、EclipseLink の 1 つの永続性ユニットで実行できますが、より複雑であり、コンテナー管理エンティティ マネージャーを使用することはできません。@PersistenceContext (EntityManager) の代わりに @PersistenceUnit (EntityManagerFactory) を注入すると、新しいログイン パラメータを createEntityManager() に渡す必要があります。「eclipselink.jdbc.exclusive-connection.mode」プロパティを「Always」(または「Isolated」にして安全なデータを分離する) に設定する必要があります。

http://wiki.eclipse.org/EclipseLink/Examples/JPA/Auditingを参照して ください。

于 2012-06-27T12:37:27.457 に答える