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.
Here is the UserManagerCode: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 sql logging of the queries that are issued when the merge and flush occurs: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(); } }
The code that generates the log messages is in the UserManager.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=?
Code:public User mergeUser(User user) { User merged = this.em.merge(user); this.em.flush(); return merged; }


Reply With Quote