JPA - 使用多个数据源来定义访问控制 [英] JPA - Using Multiple data sources to define access control
问题描述
我对JPA和JSF完全陌生,希望你能帮我解决我的问题。 我创建了2个其他数据在Glassfish JDBC资源中使用源代码jdbc / admin和jdbc / staff,并且具有不同的权限 登录/身份验证方案为: 我的代码对于上面的项目2看起来像这样: 我甚至会将我的EntityManagerFactory保留在会话属性中,并在JpaController类中检索它 问题:我怎样才能达到4或5号?这可能是 注意: 我的会话bean都是@Stateless,我试图使用@PersistenceContext和unitName,但没有unitName,但没有好运 我尝试在persistence.xml中使用多个持久性单元,希望能够使用基于持久性单元名称的用户在角色上,但是当部署到服务器时,它给了我错误。 我阅读了关于应用程序管理的持久性和 container-managed ,我想我试图实现的是使用应用程序管理,但不知道如何去做。 如果我要使用容器管理的持久性,是否可以使用多个数据源?任何建议,不胜感激。 感谢您提前发表任何意见或建议。 [已解决]
我的应用程序是使用JSF 2.0 Framework构建的,使用在Glassfish 3+,MySQL上运行的JPA 2.0 / EclipseLink。我设置了一个名为loginPU的持久性单元,使用数据源:jdbc / loginDataSource
jdbc / loginDataSource使用login1连接到MySQL(定义在 mysql
。 user 表),并且只能访问
客户
。用户
和
Map properties = new HashMap();
properties.put(TRANSACTION_TYPE,JTA);
//配置内部EclipseLink连接池
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);
//保存到会话
session.setAttribute(entityManagerFactory,emf);
//在JpaController中检索
public EntityManagerFactory getEmf(){
$ b $ HttpServletRequest request =(HttpServletRequest)FacesContext.getCurrentInstance()。getExternalContext()。getRequest() ;
HttpSession s = request.getSession(true);
尝试{
emf =(EntityManagerFactory)s.getAttribute(entityManagerFactory);
} catch(NullPointerException ne){
System.out.println(EMF Exception:+ ne);
}
返回emf;
}
吗?是否可以将数据源分配给loginPU
持久性单元?我设法使用loginPU和jdbc / loginDataSource
建立连接,然后使用jdbc / admin数据源进行连接,但是当我访问其他
实体时,它会将错误和缺省值引发至jdbc / loginDataSource
我使用由netbeans创建的JpaController类,也使用会话bean来管理实体。
我的JpaController类使用
@Resource private UserTransaction utx;
@PersistenceUnit private EntityManagerFactory emf;
@PersistenceContext
私人EntityManager em;
-
首先我定义了我的persistence.xml,如下所示:
< persistence version =2.0xmlns =http://java.sun.com/xml/ns/persistencexmlns:xsi =http:/ /www.w3.org/2001/XMLSchema-instancexsi: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>
< /余辉>
-
在会话bean中不使用任何@PersistenceUnit或@PersistenceContext。使用Netbeans创建JSF页面时创建了这些bean)
-
上面的登录方案(5个项目)已成为7:
@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();
返回em;
}
public UserFacade(){
super(User.class);
$ / code $
- 使用基于表单的用户登录认证(用户名和密码)
- 使用持久性单元loginPU和jdbc / loginDataSource创建EntityManageFactory
- 创建查询以检索用户角色
li>
- 如果用户角色是admin,使用jdbc / admin数据源连接
如果用户角色是staff,则使用jdbc / staff数据源连接
加上
- 使用
删除或清除在项目2中创建的EntityManagerFactory emf.close();
- 保留在项目4中创建的新EntityManagerFactory或5 in
HttpSession
可能最好在Persis中使用三个单独的持久性单元tence.xml,如果你需要三个不同的登录。或者只是一个拥有完全访问权限的单一登录并验证应用程序中的安全性(无论如何你似乎都在这样做)。
部署时出现什么错误?
您可以在EclipseLink中使用一个持久性单元来执行此操作,但涉及更多,并且您无法使用容器管理实体管理器。你会注入@PersistenceUnit(EntityManagerFactory)而不是@PersistenceContext(EntityManager),那么你需要将新的登录参数传递给createEntityManager()。您需要将eclipselink.jdbc.exclusive-connection.mode属性设置为始终(或隔离并隔离安全数据)。
请参阅
http://wiki.eclipse.org/EclipseLink/Examples/JPA /审核
I am totally new to JPA and JSF and hope you can help me with my questions. My application is built using JSF 2.0 Framework, using JPA 2.0/EclipseLink running on Glassfish 3+, MySQL.
I set one persistence unit called "loginPU" using data source: "jdbc/loginDataSource"
"jdbc/loginDataSource" connects to MySQL using "login1" (defined in mysql
.user
table) and only has access to customer
.user
and customer
.roles
tables, with only select privileges.
I created 2 other data sources "jdbc/admin" and "jdbc/staff" in Glassfish JDBC Resources and both with different privileges
The login/authentication scenario is:
- User login using form based authentication (username and password)
- Create EntityManageFactory using persistence unit "loginPU" and "jdbc/loginDataSource"
- create query to retrieve user role
- if user role is admin, connect using "jdbc/admin" data source
- if user role is staff, connect using "jdbc/staff" data source
My code for item 2 above looks like this:
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);
I even keep my EntityManagerFactory in session attributes and retrieve it in the JpaController class
//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;
}
Questions: How can I achieve number 4 or number 5? Is that possible to do? Is it possible to assign either data source to "loginPU" persistence unit? I manage to establish connection using loginPU and jdbc/loginDataSource and then connect using jdbc/admin datasource, but when I access other entities, it throws error and default to jdbc/loginDataSource
Note: I am using JpaController classes created by netbeans, and also session beans to manage the entities. My JpaController classes use
@Resource private UserTransaction utx;
@PersistenceUnit private EntityManagerFactory emf;
My session beans are all @Stateless, I tried to use @PersistenceContext with unitName and without unitName but no luck
@PersistenceContext
private EntityManager em;
I tried using multiple persistence units in persistence.xml, hoping to connect users using the persistence unit name based on the role, but it gives me error when deploying to server.
I read about application-managed persistence and container-managed, I think what I am trying to achieve is to use application-managed, but not sure how to do it.
If I am to use container-managed persistence, is it possible to use multiple data sources? Any suggestion is greatly appreciated.
Thank you for any comments or suggestions in advance.
[SOLVED]
First I defined my persistence.xml as follows:
<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>
I don't use any @PersistenceUnit or @PersistenceContext in my session beans.(I'm using Netbeans and these beans were created when I created JSF Pages from Entity Classes)
In all session beans, they look like this:
@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); } }
The login scenario above (5 items) has become 7:
- User login using form based authentication (username and password)
- Create EntityManageFactory using persistence unit "loginPU" and "jdbc/loginDataSource"
- create query to retrieve user role
- if user role is admin, connect using "jdbc/admin" data source
- if user role is staff, connect using "jdbc/staff" data source
plus
- remove or clear EntityManagerFactory created in item 2 using emf.close();
- Keep new EntityManagerFactory created in either item 4 or 5 in HttpSession
You are probably best off using three separate persistence units in your persistence.xml if you need three different logins. Or just have a single login with full access and validate security in your application (which you seem to be doing in part anyway).
What error did you get on deploy?
You can do it with one persistence unit in EclipseLink but it is more involved, and you cannot use container managed entity managers. You would inject a @PersistenceUnit (EntityManagerFactory) instead of an @PersistenceContext (EntityManager), then you would need to pass the new login parameters to createEntityManager(). You would need to set the "eclipselink.jdbc.exclusive-connection.mode" property to "Always" (or "Isolated" and make the secure data isolated).
See, http://wiki.eclipse.org/EclipseLink/Examples/JPA/Auditing
这篇关于JPA - 使用多个数据源来定义访问控制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!