Results 1 to 2 of 2

Thread: how to eliminate auto generated select queries when executing EntityManager.merge

Threaded View

  1. #1
    Join Date
    Feb 2012
    Posts
    1

    Default how to eliminate auto generated select queries when executing EntityManager.merge

    I'm fairly new to Spring so please bear with me. I have two Spring MVC Controllers, a Register controller and EditProfile controller. The Register controller allows a user to register (inserts a new User using entityManager.persist) and the EditProfile controller updates a logged in user (using entityManager.merge). When a user's profile is updated using merge, two select queries are automatically issued before the SQL update. I believe this is to reattach the user object to the PersistenceContext since merge (I believe) works only on attached objects. My question is: How can I eliminate the two select queries from being issued? This seems like an unecessary performance hit.

    Here is my EditProfile controller.

    Code:
    package com.idream.servlet;
    
    import javax.servlet.http.HttpServletRequest;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.validation.BindingResult;
    import org.springframework.web.bind.annotation.ModelAttribute;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.SessionAttributes;
    
    import com.idream.manager.StateManager;
    import com.idream.manager.UserManager;
    import com.idream.model.Role;
    import com.idream.model.User;
    
    @Controller
    @RequestMapping(value="/editprofile")
    public class EditProfile {
    
    	@Autowired
    	private UserManager userManager;
    	
    	@Autowired
    	private StateManager stateManager;
    	
    	@RequestMapping(method = RequestMethod.GET)
    	public String setupForm(Model model, HttpServletRequest request) {
    		
    		model.addAttribute("stateList", stateManager.getStatesForDropdown());
    		model.addAttribute("user", request.getSession().getAttribute("user"));
    		
    		return "editprofile/edit";
    	}	
    	
    	
    	private void updateSessionUser(User user, HttpServletRequest request) {
    		
    		User sessionUser = (User)request.getSession().getAttribute("user");
    		
    		sessionUser.setFirstName(user.getFirstName());
    		sessionUser.setLastName(user.getLastName());
    		sessionUser.setAddress1(user.getAddress1());
    		sessionUser.setAddress2(user.getAddress2());
    		sessionUser.setCity(user.getCity());
    		sessionUser.setState(user.getState());
    		sessionUser.setZipCode(user.getZipCode());
    		sessionUser.setAutoSave(user.getAutoSave());
    		
    		
    	}
    	
    	private void 
    			fixUpModelUser(User springModelUser, 
    					User sessionUser) {
    
    		/**
    		 * update the spring model user so that it can be persisted.
    		 * it needs the fields that aren't updated by the form (email password)
    		 * and the user id (so that jpa can detect that's it's already
    		 * there and update not insert)
    		 */
    		springModelUser.setUserId(sessionUser.getUserId());
    		springModelUser.setEmail(sessionUser.getEmail());
    		springModelUser.setPassword(sessionUser.getPassword());
    		
    		Role r = new Role();
    		r.setRoleId(1);
    		springModelUser.setRole(r); //set role to customer
    		
    		
    	}
    	
    	@RequestMapping(method = RequestMethod.POST)
    	/**
    	public String onSubmit(@ModelAttribute("user") User user, BindingResult result, Model model,
    			HttpServletRequest request) {
    	 */
    	
    	public String onSubmit(@ModelAttribute("user") User user, BindingResult result, Model model,
    				HttpServletRequest request) {
    		
    		
    		
    		fixUpModelUser(user, (User)request.getSession().getAttribute("user"));
    		//updateSessionUser(user, request);
    		
    		//User u = (User)request.getSession().getAttribute("user");
    		
    		//user.setUserId(u.getUserId()); //update the spring user so it has a user id, this way
    		
    		//it can be updated by jpa
    		
    		//System.out.println(u.getUserId());
    		
    		model.addAttribute("stateList", stateManager.getStatesForDropdown());
    		
    		if (user.getState() != null && user.getState().trim().equals("NONE")) {
    			user.setState(null);
    		}
    		
    		userManager.mergeUser(user);
    		//userManager.flush();
    		
    		//update session user to have new values that were entered into the form
    		
    		updateSessionUser(user, request);		
    		
    		return "editprofile/edit";
    	}
    	
    }
    Here is the UserManager

    Code:
    package com.idream.manager;
    
    import java.util.List;
    
    import javax.persistence.EntityManager;
    import javax.persistence.PersistenceContext;
    import javax.persistence.PersistenceContextType;
    import javax.persistence.Query;
    
    import org.springframework.stereotype.Repository;
    import org.springframework.transaction.annotation.Transactional;
    
    import com.idream.model.User;
    
    
    @Transactional
    public class UserManager {
    
    	//@PersistenceContext(type=PersistenceContextType.TRANSACTION)
    	@PersistenceContext
    	private EntityManager em;
    	
    
    	@PersistenceContext public void setEntityManager(EntityManager em) { this.em = em; }
    	
    	//@Transactional(readOnly = true)
    	@SuppressWarnings("unchecked")
    	public User getUserByEmail(String email) {
    		Query query = this.em.createQuery("SELECT user FROM User user where user.email = :email1 ");
    		
    		query.setParameter("email1", email);
    		
    		List list = query.getResultList();
    		
    		if (list == null || list.size() == 0) return null;
    		
    		return (User)list.get(0);
    	}
    
    
    	
    	public void persistUser(User user) {
    		
    		this.em.persist(user);
    		
    		
    	}
    	
    	//@Transactional(propagation = Propagation.REQUIRED)
    
    	public User mergeUser(User user) {
    		
    	
    		//EntityTransaction t = em.getTransaction();
    		
    		
    		
    		User merged = this.em.merge(user);
    		this.em.flush();
    		
    		
    		return merged;
    	}
    	
    	public void flush() {
    		this.em.flush();		
    	}
    	
    	
    	
    }
    Here is the sql logging of the queries that are issued when the merge and flush occurs:


    Code:
    Hibernate: select user0_.user_id as user1_1_0_, user0_.address1 as address2_1_0_, user0_.address2 as address3_1_0_, user0_.auto_save as auto4_1_0_, user0_.city as city1_0_, user0_.date_saved as date6_1_0_, user0_.email as email1_0_, user0_.first_name as first8_1_0_, user0_.last_name as last9_1_0_, user0_.password as password1_0_, user0_.role_id as role14_1_0_, user0_.state as state1_0_, user0_.verified as verified1_0_, user0_.zip_code as zip13_1_0_ from User user0_ where user0_.user_id=?
    Hibernate: select role0_.role_id as role1_4_0_, role0_.date_saved as date2_4_0_, role0_.role_name as role3_4_0_ from Role role0_ where role0_.role_id=?
    Hibernate: update User set address1=?, address2=?, auto_save=?, city=?, date_saved=?, email=?, first_name=?, last_name=?, password=?, role_id=?, state=?, verified=?, zip_code=? where user_id=?
    The code that generates the log messages is in the UserManager.


    Code:
    public User mergeUser(User user) {
    		
    		User merged = this.em.merge(user);
    		this.em.flush();
    		
    		
    		return merged;
    	}
    Last edited by vonrosen; Feb 10th, 2012 at 12:34 PM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •