如何在Spring

时间:2015-06-17 12:07:13

标签: java spring hibernate

我是spring + hibernate的新手。当我添加客户及其目的地(一对多关系)时,一切都很好。但是当我更新客户的目的地时,所有以前的目的地都使用空的客户外键保留在数据库中。

假设我插入4个目的地a,b,c,d。更新客户后,我插入x,y。然后它存储了总共6个目的地:a,b,c,d带有空引用,x,y带有客户引用。

这是我的代码:

1)。客户实体

与目的地和关系的一对多关系是单向的。

@Entity
@Table(name="customers")
@Proxy(lazy=false)
public class CustomerEntity {   

    @Id
    @Column(name="id")
    @GeneratedValue
    private Integer id;

    private String description; 
    private String panNo;
    private String cstNo;
    private String vatNo;

    @OneToMany(fetch = FetchType.EAGER,cascade = CascadeType.ALL)
    @JoinColumn(name = "customer_id", referencedColumnName = "id")
    public List<DestinationsEntity> destination = new AutoPopulatingList<DestinationsEntity>(DestinationsEntity.class);

    //getter and setters
}

2)。目的地实体

@Entity
@Table(name = "destinations")
@Proxy(lazy = false)
public class DestinationsEntity {

  @Id
  @Column(name = "id")
  @GeneratedValue
  private Integer id;

  @Column(name="destination")
  private String destination;
  // getter and setter
}

1)。 AddCustomer.jsp

此代码用于在自动填充列表中添加更多目的地

        <div id="destination_container">
                <div><textarea row="3" col="5" class="destination_address" name= "destination[${0}].destination" placeholder="Please enter address"></textarea></div>
        </div>

        <script type="text/javascript">
                $(document).ready(function(){

                    var index = 1;
                /*
                * Add more destination
                */

                $('#add_more_destination').click(function(){
                        $('#destination_container').append('<div><textarea row="3" col="5" class="destination_address" name= "destination[${"'+index+'"}].destination" placeholder="Please enter address"></textarea><span class="remove_dest">*</span></div>');
                        index++;
                });
            });
        </script>

2)。 updateCustomer.jsp

客户添加的所有目的地都显示在此处,他/她可以更改目的地(如插入pune,mumbai,banglore之前),现在更新目的地(德里,旁遮普)

        <c:set var="index" scope="page" value="${fn:length(destinationss)}"/>
        <c:forEach items="${destinationss}" var="dest" varStatus="i">   
        <div>
            <textarea class="destination_address" name= "destination[${i.index}].destination" placeholder="Please enter address">${dest.destination}</textarea><span class="remove_dest">*</span>
        </div>  
        </c:forEach>
        <button type ="button" id="add_more_destination">Add More Destinations</button>

        <script type="text/javascript">
                $(document).ready(function(){

                /*
                * Add a destination
                */

                var index = ${index};
                $('#add_more_destination').click(function(){
                        $('#destination_container').append('<div><textarea row="3" col="5" class="destination_address" name=destination["'+index+'"].destination placeholder="Please enter address"></textarea><span class="remove_dest">*</span></div>');  
                        alert(index);
                        index++;
                });
        </script>

控制器

@RequestMapping(value = "/addCustomerForm", method = RequestMethod.GET)
public String addCustomerForm(ModelMap map) {
    return "master/addCustomer";
}


@RequestMapping(value = "/addCustomer", method = RequestMethod.POST)
public String addCustomer(@ModelAttribute(value = "customer") CustomerEntity customer,BindingResult result, HttpServletRequest request) {
    customerService.addCustomer(customer);
    return "redirect:/customer";
}

更新客户

这是我昨晚尝试的新事物。问题部分解决了。

@ModelAttribute
public void updateOperation(HttpServletRequest request, ModelMap map) {
    if(null !=request.getParameter("id"))
       map.addAttribute("customer1", customerService.findOne(Integer.parseInt(request.getParameter("id"))));
    }

    @RequestMapping(value = "/updateCustomerForm/{customerId}", method = RequestMethod.GET)
    public String updateCustomerForm(@PathVariable("customerId") Integer customerId, ModelMap map, HttpServletRequest request) {
       CustomerEntity customerEntity = customerService.findOne(customerId);
       map.addAttribute("customer", customerEntity);
                map.addAttribute("destinationss",customerEntity.getDestination());
    }

    @RequestMapping(value = "/updateCustomer", method = RequestMethod.POST)
    public String updateCustomer(@ModelAttribute(value = "customer1")CustomerEntity customer1,BindingResult result, HttpServletRequest request,HttpServletResponse response) {
       customerService.updateCustomer(customer1);
       return "redirect:/customer";
    }
}    

1)。 CustomerServiceImpl

public class CustomerServiceImpl implements CustomerService{

   @Autowired
   private CustomerDao customerDao;

   @Override
   @Transactional
   public void addCustomer(CustomerEntity customer) {
      customerDao.addCustomer(customer);
   }    

   @Override
   @Transactional
   public CustomerEntity findOne(Integer id){
      return customerDao.findOne(id);
   }

   @Override
   @Transactional
   public void updateCustomer(CustomerEntity customerEntity){
      if (null != customerEntity) {
        customerDao.updateCustomer(customerEntity);     
      }
   }
}        

2).CustomerDaoImpl

public class CustomerDaoImpl implements CustomerDao{
   @Autowired
   private SessionFactory sessionFactory;

   @Override
   @Transactional
   public void addCustomer(CustomerEntity customer){
      this.sessionFactory.getCurrentSession().save(customer);
   }

   @Override
   public CustomerEntity findOne(Integer id){
      return (CustomerEntity) sessionFactory.getCurrentSession().load(CustomerEntity.class, id);
   }

   @Override
   @Transactional
   public void updateCustomer(CustomerEntity customerEntity){
         if (null != customerEntity) {
                   this.sessionFactory.getCurrentSession().update(customerEntity);
         }
   }
}

1 个答案:

答案 0 :(得分:0)

问题是Spring会给你新的Customer实体,所以我猜这个Customer中的Destination实体最初是空的。因此,在您的更新操作中,您只需添加一些新的目标实体,然后根据您的代码将它们添加到客户。

因此,在这种情况下,客户实体只有新的目标对象,因为先前映射的现有目标实体不存在于您的客户实体中。

要解决此问题,首先从数据库获取Customer实体,然后此实体将具有一组Destination对象。现在,对于此客户,您可以添加新的Destination对象,并在需要时更新现有的Destination对象,然后请求Hibernate执行更新操作。在这种情况下,Hibernate可以看到您之前的目标对象以及新的目标对象,并且基于它将运行插入&amp;更新查询。

代码看起来像这样:

// First get the customer object from database:
Customer customer = (Customer) this.sessionFactory.getCurrentSession().get(Customer.class, customerId);

// Now add your destination objects, if you want you can update the existing destination entires here.

for (int i = 0; i < destinationAddrs.length; i++) {
                    DestinationsEntity destination = new DestinationsEntity();
                    destination.setDestination(destinationAddrs[i]);
                                customer.getDestinationEntity().add(destination);


                }

// Then do the update operation    
this.sessionFactory.getCurrentSession().update(customer);