私はJPAとJSFにまったく慣れていないので、質問に答えていただければ幸いです。私のアプリケーションは、JSF 2.0フレームワークを使用して構築されており、Glassfish 3以降、MySQLで実行されているJPA 2.0/EclipseLinkを使用しています。
データソースを使用して「loginPU」という永続ユニットを1つ設定しました。「jdbc/loginDataSource」「jdbc/loginDataSource」は「login1」(mysql
。user
tableで定義)を使用してMySQLに接続し、にのみアクセスできますcustomer
。user
およびcustomer
。roles
選択権限のみを持つテーブル。
GlassfishJDBCResourcesで他の2つのデータソース「jdbc/admin」と「jdbc/staff」を作成しましたが、どちらも異なる権限を持っています
ログイン/認証のシナリオは次のとおりです。
- フォームベースの認証(ユーザー名とパスワード)を使用したユーザーログイン
- 永続ユニット「loginPU」および「jdbc/loginDataSource」を使用してEntityManageFactoryを作成します
- ユーザーロールを取得するためのクエリを作成する
- ユーザーロールがadminの場合、「jdbc/admin」データソースを使用して接続します
- ユーザーロールがスタッフの場合、「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で複数の永続性ユニットを使用しようとしましたが、サーバーにデプロイするときにエラーが発生します。
アプリケーション管理の永続性とコンテナー管理について読みました。私が達成しようとしているのは、アプリケーション管理を使用することだと思いますが、その方法がわかりません。
コンテナ管理の永続性を使用する場合、複数のデータソースを使用することは可能ですか?どんな提案でも大歓迎です。
よろしくお願いします。
[解決済み]
まず、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>
セッションBeanで@PersistenceUnitまたは@PersistenceContextを使用していません(Netbeansを使用しており、これらのBeanはエンティティクラスからJSFページを作成したときに作成されました)
すべてのセッション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); } }
上記のログインシナリオ(5項目)は7になりました:
- フォームベースの認証(ユーザー名とパスワード)を使用したユーザーログイン
- 永続ユニット「loginPU」および「jdbc/loginDataSource」を使用してEntityManageFactoryを作成します
- ユーザーロールを取得するためのクエリを作成する
- ユーザーロールがadminの場合、「jdbc/admin」データソースを使用して接続します
- ユーザーロールがスタッフの場合、「jdbc/staff」データソースを使用して接続します
プラス
- emf.close();を使用して、項目2で作成されたEntityManagerFactoryを削除またはクリアします。
- HttpSessionの項目4または5のいずれかで作成された新しいEntityManagerFactoryを保持します