我对 JPA 和 JSF 完全陌生,希望您能帮助我解决我的问题。我的应用程序是使用 JSF 2.0 框架构建的,使用在 Glassfish 3+、MySQL 上运行的 JPA 2.0/EclipseLink。
我使用数据源设置了一个名为“loginPU”的持久性单元:“jdbc/loginDataSource”“jdbc/loginDataSource”使用“login1”(在 .table 中定义)连接到 MySQL,mysql
并且user
只能访问customer
. user
和customer
。roles
表,只有选择权限。
我在 Glassfish JDBC 资源中创建了 2 个其他数据源“jdbc/admin”和“jdbc/staff”,并且都具有不同的权限
登录/认证场景是:
- 使用基于表单的身份验证(用户名和密码)的用户登录
- 使用持久性单元“loginPU”和“jdbc/loginDataSource”创建 EntityManageFactory
- 创建查询以检索用户角色
- 如果用户角色是管理员,则使用“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,我尝试使用 @PersistenceContext 和 unitName 和没有 unitName 但没有运气
@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
- 创建查询以检索用户角色
- 如果用户角色是管理员,则使用“jdbc/admin”数据源进行连接
- 如果用户角色是人员,则使用“jdbc/staff”数据源进行连接
加
- 使用 emf.close() 删除或清除在第 2 项中创建的 EntityManagerFactory;
- 保持在 HttpSession 的第 4 项或第 5 项中创建的新 EntityManagerFactory