JPA-使用多个数据源定义访问控制
我对JPA和JSF完全陌生,希望你能帮助我回答我的问题。 我的应用程序是使用JSF2.0框架构建的,使用运行在GlassFish3+、MySQL上的JPA2.0/EclipseLink 我使用数据源“jdbc/logindasource”设置了一个名为“loginPU”的持久化单元 “jdbc/loginDataSource”使用“login1”(在JPA-使用多个数据源定义访问控制,jpa,glassfish,eclipselink,persistence-unit,Jpa,Glassfish,Eclipselink,Persistence Unit,我对JPA和JSF完全陌生,希望你能帮助我回答我的问题。 我的应用程序是使用JSF2.0框架构建的,使用运行在GlassFish3+、MySQL上的JPA2.0/EclipseLink 我使用数据源“jdbc/logindasource”设置了一个名为“loginPU”的持久化单元 “jdbc/loginDataSource”使用“login1”(在MySQLuser表中定义)连接到MySQL,并且只能访问customer和customer角色表,并且只有选择权限 我在Glassfish jdb
MySQL
user
表中定义)连接到MySQL,并且只能访问customer
和customer
角色表,并且只有选择权限
我在Glassfish jdbc资源中创建了另外两个数据源“jdbc/admin”和“jdbc/staff”,它们都具有不同的权限
登录/身份验证场景为:
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);
@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);
}
}
我甚至将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 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>
org.eclipse.persistence.jpa.PersistenceProvider
jdbc/登录
假的
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);
@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);
}
}
@无状态
公共类UserFacade扩展了AbstractFacade{
@凌驾
受保护的EntityManager getEntityManager(){
HttpSession会话=(HttpSession)FacesContext.getCurrentInstance().getExternalContext().getSession(false);
EntityManagerFactory emf=(EntityManagerFactory)session.getAttribute(“EntityManagerFactory”);
EntityManager em=emf.createEntityManager();
返回em;
}
公共UserFacade(){
super(User.class);
}
}
如果您需要三个不同的登录名,那么最好在persistence.xml中使用三个独立的持久性单元。或者只需要一个具有完全访问权限的单一登录,并验证应用程序中的安全性(不管怎么说,您似乎正在部分地这样做) 部署时出现了什么错误 您可以使用EclipseLink中的一个持久化单元来完成这项工作,但它更复杂,并且您不能使用容器管理的实体管理器。您需要注入@PersistenceUnit(EntityManagerFactory)而不是@PersistenceContext(EntityManager),然后需要将新的登录参数传递给createEntityManager()。您需要将“eclipselink.jdbc.exclusive connection.mode”属性设置为“始终”(或“隔离”,并隔离安全数据) 看,,
我不明白您为什么要使用这种笨重的方式来获取
EntityManagerFactory
:这是您尝试动态检索PersistenceContext
的方式吗?我不确定最好的方式是什么,感谢您指出它很笨重。非常感谢你的指导。谢谢你的回答,詹姆斯。你的意思是我可以使用相同的持久化单元和相同的数据源,唯一不同的是在创建EntityManager时传递不同的属性(用户和密码)?我会试试这个并公布我的结果。这对你来说可能听起来很愚蠢。我从我的JPA控制器创建EntityManager,并传递“admin”用户的属性,然后使用EM创建查询,但错误消息显示“SELECT command DENITED to user'login1'@“localhost”for table'user_activity'”,这意味着EM仍然默认为“login1”,这是我第一次进行身份验证时使用的用户。