Spring mvc 通过EntityManager更新数据库

Spring mvc 通过EntityManager更新数据库,spring-mvc,jpa,dao,entitymanager,Spring Mvc,Jpa,Dao,Entitymanager,我正在从事一个SpringMVC项目,试图使用jpa更新用户的用户名和密码。但我似乎没有取得任何进展D 我检查了其他问题,如,并试图使用他们批准的答案为我的案件。唉,我的数据库没有任何变化 到目前为止,我已经尝试过这些方法,但没有一种有效: 按照建议,在设置前使用持久化 按建议设置后使用合并 按照建议手动提交事务 不幸的是,这个类在我的数据库中有很多外键,我无法安全地删除旧的外键并添加一个新的Dept,其中包含新数据。所以,这里是我的更新方法-当然是DAO级别的-请有人建议一种更新用户名和密码的

我正在从事一个SpringMVC项目,试图使用jpa更新用户的用户名和密码。但我似乎没有取得任何进展D

我检查了其他问题,如,并试图使用他们批准的答案为我的案件。唉,我的数据库没有任何变化

到目前为止,我已经尝试过这些方法,但没有一种有效:

  • 按照建议,在设置前使用
    持久化

  • 按建议设置后使用
    合并

  • 按照建议手动提交事务

  • 不幸的是,这个类在我的数据库中有很多外键,我无法安全地删除旧的外键并添加一个新的
    Dept
    ,其中包含新数据。所以,这里是我的更新方法-当然是DAO级别的-请有人建议一种更新用户名和密码的新方法吗

    @Transactional
        public  Dept updateDept(int depId, String u, String p) {
            System.err.println("successfully reached DAO");
            Dept dep=entityManager.find(Dept.class,depId);
    
            dep.setUname(u);
            dep.setPassword(p);
            entityManager.merge(dep);
    
            return entityManager.find(Dept.class,depId); //just to check if update really happened, which did not
        }//end of update Dept
    
    编辑: 好吧,所以事情变得越来越复杂了。我在这方面真的是个新手,所以我尽量给你提供更多的细节

    这些是我被允许改变的唯一部分,我必须考虑到JPA等其他部分的其他配置是由我的高级队友完成的,并且是正确的。

    这是我的控制器,它应该更新部门经理的用户名和密码,并将用户发送回他们的第一页:

    @RequestMapping(value="/infoEdit", method=RequestMethod.POST)
        public String editManager(HttpServletRequest req, @RequestParam("username") String  usernname , @RequestParam("password") String password , Model model) {
            int id= (Integer) req.getSession().getAttribute("id");
    
            boolean isUpdated=managerManagerImpl.updateUserPass(id,usernname,password);
            System.err.println(isUpdated);
            Dept d= managerManagerImpl.getDeptByManagerId(usernname,password);
            if (d!=null)
    
            return "themanager/managerFirstPage";
    
        }
    
    在managerManager接口的managerManager Impl实现中,
    updateUserPass()
    如下所示:

    @Override
        public Boolean updateUserPass(int id, String usernname, String password) {
            Dept dept=managerDAOImpl.getDept(id); // who is this?
            Dept possibleDup=managerDAOImpl.getDept(usernname);//maybe this username is taken
            Dept newDep=null;
            if(possibleDup==null || (possibleDup!=null && possibleDup.getId()==dept.getId())){//username is not taken
                System.err.println("going to update it!!");
                newDep=managerDAOImpl.updateDept(dept.getId(),usernname,password);
                System.err.println("newDep data here            : " + newDep.getId() + "// "+newDep.getUname());
                Dept newnewDept = managerDAOImpl.getDept(id);
                if(newnewDept!=null)
                    System.err.println("&& newnewDep data here            : " + newnewDept.getId() + "// "+newnewDept.getUname());
            }
            Boolean isUpdated=(null!=newDep && newDep.getId()==dept.getId());
            return isUpdated;
        }
    
    @Transactional
        public  void updateDept(Dept dep,String username, String password)  {
            entityManager.clear();
            dep.setUname(username);
            dep.setPassword(password);
            entityManager.merge(dep);
        }//end of update Dept
    
    这是我的整个managerDAOImpl课程:

    @Repository
    public class TheManagerDAOImpl {
    
        public TheManagerDAOImpl() {
        }
    
        @PersistenceContext
        public EntityManager entityManager;
    
    
        @Transactional
        public Prof getManager(String usern){
            String hql="SELECT p FROM Dept  p WHERE p.uname=:username";
            Query q= entityManager.createQuery(hql);
            q.setParameter("username",usern);
            List<Prof> res = (List<Prof>) q.getResultList();
            return res == null || res.size() == 0 ? null : res.get(0);
        }
        @Transactional
        public Dept getDept(int managerId) {
            String hql= "SELECT d FROM Dept  d WHERE  d.id=:idHere";
            Query q= entityManager.createQuery(hql);
            q.setParameter("idHere",managerId);
            List<Dept> res = (List<Dept>) q.getResultList();
            return res == null || res.size() == 0 ? null : res.get(0);
        }
        @Transactional
        public Dept getDept(String managerId, String managerPass) {
            String hql= "SELECT d FROM Dept  d WHERE d.uname=:username AND d.password=:pass";
            Query q= entityManager.createQuery(hql);
            q.setParameter("username",managerId);
            q.setParameter("pass",managerPass);
            List<Dept> res = (List<Dept>) q.getResultList();
            return res == null || res.size() == 0 ? null : res.get(0);
        }
    
        @Transactional
        public Dept getDept(String managerId) {
            String hql= "SELECT d FROM Dept  d WHERE d.uname=:username";
            Query q= entityManager.createQuery(hql);
            q.setParameter("username",managerId);
            List<Dept> res = (List<Dept>) q.getResultList();
            return res == null || res.size() == 0 ? null : res.get(0);
        }
        @Transactional
        public  Dept updateDept(int depId, String u, String p) {
            System.err.println("**************************here in dao");
            Dept dep=entityManager.find(Dept.class,depId);
    
            dep.setUname(u);
            dep.setPassword(p);
            entityManager.merge(dep);
    
            return entityManager.find(Dept.class,depId);
        }//end of update Dept
    
    
    }
    
    @存储库
    公共类TheManagerDAOImpl{
    公共TheManagerDAOImpl(){
    }
    @持久上下文
    公共实体管理者实体管理者;
    @交易的
    public Prof getManager(字符串用户n){
    String hql=“从p部门选择p,其中p.uname=:username”;
    Query q=entityManager.createQuery(hql);
    q、 setParameter(“用户名”,usern);
    List res=(List)q.getResultList();
    返回res==null | | res.size()==0?null:res.get(0);
    }
    @交易的
    公共部门getDept(int managerId){
    String hql=“从部门d中选择d,其中d.id=:idHere”;
    Query q=entityManager.createQuery(hql);
    q、 setParameter(“idHere”,managerId);
    List res=(List)q.getResultList();
    返回res==null | | res.size()==0?null:res.get(0);
    }
    @交易的
    公共部门getDept(字符串managerId、字符串managerPass){
    String hql=“从d部门选择d,其中d.uname=:用户名和d.password=:pass”;
    Query q=entityManager.createQuery(hql);
    q、 setParameter(“用户名”,managerId);
    q、 setParameter(“通过”,managerPass);
    List res=(List)q.getResultList();
    返回res==null | | res.size()==0?null:res.get(0);
    }
    @交易的
    公共部门getDept(字符串managerId){
    String hql=“从部门d中选择d,其中d.uname=:用户名”;
    Query q=entityManager.createQuery(hql);
    q、 setParameter(“用户名”,managerId);
    List res=(List)q.getResultList();
    返回res==null | | res.size()==0?null:res.get(0);
    }
    @交易的
    public Dept updateDept(int depId,字符串u,字符串p){
    System.err.println(“*********************************这里在dao中”);
    Dept dep=entityManager.find(Dept.class,depId);
    副秘书长(u);
    副设置密码(p);
    实体管理器合并(dep);
    返回entityManager.find(部门类,部门ID);
    }//更新部门结束
    }
    

    只需提及,这些System.error内容用于确保它实际调用这些方法,并且完全无关。

    您正在获取容器管理器持久化上下文,它必须获取JTA数据源,但正如我之前从persistence.xml中看到的(您已经删除了它),您正在使用资源本地事务(通过指定jdbc资源)

    正确的配置应该是(对于XML配置)

    1) 您的数据源

    <jdbc:embedded-database id="dataSource" type="H2">
        </jdbc:embedded-database>
    // or jdbc:initialize-database for non-embedded
    
    
    //或jdbc:为非嵌入式数据库初始化数据库
    
    2) 您的事务管理器

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
                    <property name="entityManagerFactory" ref="emf"/>
                </bean>
    
    
    
    2.1)当您使用注释进行事务划分时,您需要

    <tx:annotation-driven transaction-manager="transactionManager" />
    
    
    
    3) 您的实体经理工厂

    bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
            <property name="dataSource" ref="dataSource" />
            <property name="jpaVendorAdapter">
                <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
                </property>
                <property name="packagesToScan" value="com.myPackage"/>
                <property name="jpaProperties">
                    <props>
                        <prop key="hibernate.dialect">org.hibernate.dialect.H2Dialect</prop>
                        <prop key="hibernate.max_fetch_depth">3</prop>
                        <prop key="hibernate.jdbc.fetch_size">50</prop>
                        <prop key="hibernate.jdbc.batch_size">10</prop>
                        <prop key="hibernate.show_sql">true</prop>
                    </props>
                </property>
            </bean>
    
    bean id=“emf”class=“org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean”>
    org.hibernate.dial.h2方言
    3.
    50
    10
    真的
    
    我找到了另一种方法来进行更新,我不确定它是否有任何缺点,或者它将来会毁掉我的代码。但既然它现在解决了这个问题,我在这里分享它。也许会有帮助

    目前,在更新任何现有实体之前,我先清除我的
    entityManager
    。不知怎的,是这样的:

    @Override
        public Boolean updateUserPass(int id, String usernname, String password) {
            Dept dept=managerDAOImpl.getDept(id); // who is this?
            Dept possibleDup=managerDAOImpl.getDept(usernname);//maybe this username is taken
            Dept newDep=null;
            if(possibleDup==null || (possibleDup!=null && possibleDup.getId()==dept.getId())){//username is not taken
                System.err.println("going to update it!!");
                newDep=managerDAOImpl.updateDept(dept.getId(),usernname,password);
                System.err.println("newDep data here            : " + newDep.getId() + "// "+newDep.getUname());
                Dept newnewDept = managerDAOImpl.getDept(id);
                if(newnewDept!=null)
                    System.err.println("&& newnewDep data here            : " + newnewDept.getId() + "// "+newnewDept.getUname());
            }
            Boolean isUpdated=(null!=newDep && newDep.getId()==dept.getId());
            return isUpdated;
        }
    
    @Transactional
        public  void updateDept(Dept dep,String username, String password)  {
            entityManager.clear();
            dep.setUname(username);
            dep.setPassword(password);
            entityManager.merge(dep);
        }//end of update Dept
    

    令人惊讶的是,它现在运行良好,并在DB上提交更新。

    您可以共享您的持久性配置吗?entityManager.merge()完全没有用处:您已经有了一个托管实体。并且返回严格等同于
    返回dep
    。我的猜测是,问题在于如何获得实体管理器或包含此方法的类的实例。或者在spring配置中。您需要向我们展示更多的代码和配置。可能您在spring中的JPA配置不正确。@DmitrySenkovich我不是这些方面的专家,您能准确地解释一下我应该在我的问题中添加哪个文件吗?据我所知,这里有一个持久性上下文,我刚才提到它是为了启动我的entityManager。抱歉:“>@Sarah Amini我需要你设置持久性。如果你使用Spring或java配置,我可能会在Spring xml配置文件中找到。你如何设置
    entityManagerFactory
    ?抱歉,我认为该文件与此无关。我得到了一个简短的解决方案,并尝试了它。不是苏