通过EntityManager更新DB

时间:2017-06-23 13:22:32

标签: spring-mvc jpa dao entitymanager

我正在开发一个Spring-MVC项目,尝试使用jpa更新用户的用户名和密码。但我似乎没有取得任何进展。 :d

我查看了其他问题,例如this one,并尝试将他们批准的答案用于我的案例。唉,我的数据库没有任何变化。

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

  1. 在设置之前使用persist,如建议here

  2. 设置为建议here

    后,使用merge
  3. 按照建议here手动提交交易。

  4. 不幸的是,这个类在我的数据库周围有很多外键,我不能安全删除旧的,并添加一个新的Dept新数据。所以,这里是我的更新方法-in 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";
    
        }
    

    在managerManagerImpl中 - managerManager接口的实现,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;
        }
    

    这是我的整个经理DAOImpl类:

    @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
    
    
    }
    

    请注意,那些System.error的东西用于确保它实际上调用这些方法,并且完全不相关。

2 个答案:

答案 0 :(得分:0)

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

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

1)您的数据源

<jdbc:embedded-database id="dataSource" type="H2">
    </jdbc:embedded-database>
// or jdbc:initialize-database for non-embedded

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>

答案 1 :(得分:0)

我找到了另一种做更新的方法,我不确定它是否有任何缺点,否则将来会破坏我的代码。但由于它现在解决了这个问题,我在这里分享。也许它会有所帮助。

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

@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更新。