Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JPA-使用多个数据源定义访问控制_Jpa_Glassfish_Eclipselink_Persistence Unit - Fatal编程技术网

JPA-使用多个数据源定义访问控制

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

我对JPA和JSF完全陌生,希望你能帮助我回答我的问题。 我的应用程序是使用JSF2.0框架构建的,使用运行在GlassFish3+、MySQL上的JPA2.0/EclipseLink

我使用数据源“jdbc/logindasource”设置了一个名为“loginPU”的持久化单元 “jdbc/loginDataSource”使用“login1”(在
MySQL
user
表中定义)连接到MySQL,并且只能访问
customer
customer
角色表,并且只有选择权限

我在Glassfish jdbc资源中创建了另外两个数据源“jdbc/admin”和“jdbc/staff”,它们都具有不同的权限

登录/身份验证场景为:

  • 使用基于表单的身份验证(用户名和密码)进行用户登录
  • 使用持久化单元“loginPU”和“jdbc/loginDataSource”创建EntityManageFactory
  • 创建查询以检索用户角色
  • 如果用户角色是admin,则使用“jdbc/admin”数据源进行连接
  • 如果用户角色是staff,则使用“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);
    
    @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.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/登录
    假的
    
  • 我在会话bean中不使用任何@PersistenceUnit或@PersistenceContext(我使用的是Netbeans,这些bean是在我从实体类创建JSF页面时创建的)

  • 在所有会话bean中,它们如下所示:

    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);
    }
    }
    
  • 上述登录场景(5项)已变为7项:

  • 使用基于表单的身份验证(用户名和密码)进行用户登录
  • 使用持久化单元“loginPU”和“jdbc/loginDataSource”创建EntityManageFactory
  • 创建查询以检索用户角色
  • 如果用户角色是admin,则使用“jdbc/admin”数据源进行连接
  • 如果用户角色是staff,则使用“jdbc/staff”数据源进行连接
  • 加上

  • 使用删除或清除在项目2中创建的EntityManagerFactory emf.close()
  • 保留在中的第4项或第5项中创建的新EntityManagerFactory HttpSession

  • 如果您需要三个不同的登录名,那么最好在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”,这是我第一次进行身份验证时使用的用户。