2014-04-27 2 views
1

Я делаю это следующим образом. Это заставляет меня чувствовать себя больным!Как обновить объект в jpa?

public class CounselInfoServiceImpl 
    extends BaseServiceImpl<CounselInfoDao, CounselInfoEntity, Long> 
    implements CounselInfoService { 

    @Inject 
    ClassService classService; 

    @Inject 
    @Override 
    public void setDao(CounselInfoDao dao) 
    { 
     super.setDao(dao); 
    } 

    @Override 
    public CounselInfoEntity editTo(CounselInfoEntity model) 
    { 
     CounselInfoEntity entity = id(model.getId()); 

     if (!Strings.isNullOrEmpty(model.getName())) 
     { 
      entity.setName(model.getName()); 
     } 

     if (!Strings.isNullOrEmpty(model.getAddress())) 
     { 
      entity.setAddress(model.getAddress()); 
     } 

     if (!Strings.isNullOrEmpty(model.getEducation())) 
     { 
      entity.setEducation(model.getEducation()); 
     } 

     if (!Strings.isNullOrEmpty(model.getPhone())) 
     { 
      entity.setPhone(model.getPhone()); 
     } 

     if (!Strings.isNullOrEmpty(model.getQQ())) 
     { 
      entity.setQQ(model.getQQ()); 
     } 

     if (!Strings.isNullOrEmpty(model.getRemark())) 
     { 
      entity.setPhone(model.getPhone()); 
     } 

     if (!Strings.isNullOrEmpty(model.getSchool())) 
     { 
      entity.setSchool(model.getSchool()); 
     } 

     if (model.getAge() != null) 
     { 
      entity.setAge(model.getAge()); 
     } 

     if (model.getSex() != null) 
     { 
      entity.setSex(model.getSex()); 
     } 

     if (model.getClassIntention() != null) 
     {       
      entity.setClassIntention(
         classService.id(
          model.getClassIntention().getId())); 
     } 

     return entity; 
    } 
} 

Любые предложения, чтобы избежать этого spaghetti code?

BTW, написание этого кода - тяжелая работа!

EDIT

Кстати, я не думаю, что em.merge готов к этому. См here

The EntityManager.merge() operation is used to merge the changes made to a detached object into the persistence context. 

Она отметила detached object, но модель обновления только что получила часть дня. Так что, если я сливаю модель, все значений модели будет применяться к лицу. (Например, пароль, который я не хочу, чтобы обновить и editTo не должен касаться пароля.)

+0

У вас есть странный способ сделать. Обычно при использовании приложения для редактирования объекта пользователь использует предварительно заполненную форму, содержащую все поля объекта, изменяет поля, которые необходимо изменить, представляет эту форму, и все поля, пустые или нет, записываются к объекту. Я никогда не видел форму, в которой оставить поле пустым означает «не изменять значение этого атрибута». –

+0

Нет пустого поля в форме, потому что я не буду отображать это поле. Некоторая подача проверена. Также пользователь может редактировать только часть всей даты. – wener

+0

Я не понимаю, что это значит. О какой дате вы говорите? Как выглядит форма? Что означает «проверить чувствительность»? –

ответ

0

Теперь, обновление выглядит как это.

public CounselInfoEntity editTo(CounselInfoEntity model) 
{ 
    CounselInfoEntity entity = id(model.getId()); 

    List<? extends Attribute<CounselInfoEntity, ?>> editAttrs = Lists.<Attribute<CounselInfoEntity, ?>>newArrayList(CounselInfoEntity_.name, 
    CounselInfoEntity_.address, 
    CounselInfoEntity_.education, 
    CounselInfoEntity_.phone, 
    CounselInfoEntity_.QQ, 
    CounselInfoEntity_.remark, 
    CounselInfoEntity_.school, 
    CounselInfoEntity_.age, 
    CounselInfoEntity_.sex); 

    BeanHelper.merge(entity, model, BeanHelper.skipNullOrEmpty(model, editAttrs)); 

    if (model.getClassIntention() != null) 
    {       
     entity.setClassIntention(classService.id(model.getClassIntention().getId())); 
    } 

    return entity; 
} 

Вот BeanHelper

package me.wener.practices.web.common.util; 

import com.google.common.collect.Lists; 
import java.lang.reflect.Field; 
import java.util.List; 
import javax.persistence.metamodel.Attribute; 
import lombok.extern.slf4j.Slf4j; 
import org.apache.commons.lang3.reflect.FieldUtils; 

@Slf4j 
public class BeanHelper 
{ 
    /** 
    * 获取 bean 的属性,如果属性不存在或发生异常返回null 
    */ 
    public static Object tryGetProperty(Object bean, String attrName) 
    { 
     Object property = null; 
     try 
     { 
      Field field = FieldUtils.getField(bean.getClass(), attrName, true); 
      property = field.get(bean); 
     } catch (Exception e) 
     { 
      if (log.isErrorEnabled()) 
       log.error("Exception when get property " + attrName + " on " + bean, e); 
     } 
     return property; 
    } 

    public static <T, A extends Attribute<T, ?>> Object tryGetProperty(T bean, A attr) 
    { 
     return tryGetProperty(bean, attr.getName()); 
    } 

    public static <T, A extends Attribute<T, ?>> boolean trySetProperty(T bean, A attr, Object value) 
    { 
     return trySetProperty(bean, attr.getName(), value); 
    } 

    public static boolean trySetProperty(Object bean, String attrName, Object value) 
    { 
     boolean failed = false; 
     try 
     { 
      // 对于 chain 的 setter 方法, 必须要使用 force access. 
      Field field = FieldUtils.getField(bean.getClass(), attrName, true); 
      field.set(bean, value); 
     } catch (Exception e) 
     { 
      if (log.isErrorEnabled()) 
       log.error("Exception when set property " + attrName + " on " + bean, e); 

      failed = true; 
     } 
     return !failed; 
    } 

    /** 
    * Test the value of search in attrs is make the isNull and isEmpty 
    * <p/> 
    * isEmpty will apply when value is String 
    */ 
    @SafeVarargs 
    public static <E, A extends Attribute<E, ?>> List<A> skip(Object searcher, boolean skipNull, boolean skipEmpty, A... attrs) 
    { 
     return skip(searcher, skipNull, skipEmpty, Lists.newArrayList(attrs)); 
    } 

    public static <E, A extends Attribute<E, ?>> List<A> skip(Object searcher, boolean skipNull, boolean skipEmpty, List<A> attrs) 
    { 
     List<A> list = Lists.newArrayList(); 
     boolean valid; 

     for (A attr : attrs) 
     { 
      Object value = tryGetProperty(searcher, attr.getName()); 
      valid = skipNull || value != null; 

      if (valid && skipEmpty && value instanceof String) 
       valid = ((String) value).length() != 0; 

      if (valid) 
       list.add(attr); 
     } 
     return list; 
    } 

    @SafeVarargs 
    public static <E, A extends Attribute<E, ?>> List<A> skipNullOrEmpty(Object searcher, A... attrs) 
    { 
     return skip(searcher, true, true, attrs); 
    } 

    public static <E, A extends Attribute<E, ?>> List<A> skipNullOrEmpty(Object searcher, List<A> attrs) 
    { 
     return skip(searcher, true, true, attrs); 
    } 

    @SafeVarargs 
    public static <T, A extends Attribute<T, ?>> T merge(T target, T src, A... attrs) 
    { 
     return merge(target, src, Lists.newArrayList(attrs)); 
    } 

    public static <T, A extends Attribute<T, ?>> T merge(T target, T src, List<A> attrs) 
    { 
     for (A attr : attrs) 
     { 
      String attrName = attr.getName(); 
      Object value = tryGetProperty(src, attrName); 
      trySetProperty(target, attrName, value); 
     } 

     return target; 
    } 
} 

Это один лучше, потому что

  • Это тип безопасно
  • Легко фильтровать/выбрать свойство сливаться

It inclu де

Я стараюсь изо всех сил, это лучшее, что я могу сделать.

Смежные вопросы