【发布时间】:2012-06-28 10:38:41
【问题描述】:
我对 JPA 和 JSF 完全陌生,希望您能帮助我解决我的问题。 我的应用程序是使用 JSF 2.0 框架构建的,使用在 Glassfish 3+、MySQL 上运行的 JPA 2.0/EclipseLink。
我使用数据源设置了一个名为“loginPU”的持久性单元:“jdbc/loginDataSource”
“jdbc/loginDataSource”使用“login1”(在mysql.user表中定义)连接到MySQL,并且只能访问customer.user和customer.roles表,只有选择权限.
我在 Glassfish JDBC 资源中创建了另外 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,我尝试使用 @PersistenceContext 与 unitName 和没有 unitName 但没有运气
@PersistenceContext
private EntityManager em;
我尝试在persistence.xml中使用多个持久化单元,希望根据角色使用持久化单元名称连接用户,但部署到服务器时出错。
我读到了application-managed persistence 和container-managed,我想我想要实现的是使用应用程序管理,但不知道该怎么做。
如果我要使用容器管理的持久性,是否可以使用多个数据源?非常感谢任何建议。
提前感谢您的任何 cmets 或建议。
[已解决]
-
首先我将我的 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”数据源进行连接
加
- 删除或清除在第 2 项中创建的 EntityManagerFactory 使用 emf.close();
- 保留在项目 4 或 5 中创建的新 EntityManagerFactory HttpSession
【问题讨论】:
-
我不明白您为什么要使用这种繁琐的方式来获取
EntityManagerFactory:这是您尝试动态检索PersistenceContext的一种方式吗? -
我不确定最好的方法是什么,感谢您指出它很麻烦。非常感谢您的指导。
标签: jpa glassfish eclipselink persistence-unit