繁体   English   中英

如何在JPA中更新实体?

[英]How to update an entity in 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吗?

顺便说一句,编写此代码是一项艰苦的工作!

编辑

顺便说一句,我不认为em.merge已经为此做好了准备。 这里

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

它提到了detached object ,但是更新模型只是花费了一些时间。 因此,如果我合并模型,则模型的所有值都将应用于实体。(例如,密码,我不想更新, editTo不应触摸密码。)

现在,更新看起来像这样。

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

这个更好,因为

  • 类型安全
  • 易于过滤/选择要合并的属性

它包括

我尽力而为,这是我所能做到的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM