首先,数据库的增删改查都是在PersonRepository中实现,因此,直接进入PersonRepository,找到其父类,搜索delete。

    @Override
    @TransactionalMethod
    public void delete(String id) {
        Object entity = findEntity(id);
        deleteEntity(entity);
    }
  protected void deleteEntity(Object entity) {    throw new UnsupportedRequestException("Deleting " + ApiUtils.getResourceType(this.getEntityClass()) + " is not supported");  }
 

sunny之前重写的是delete方法,后面改成重写deleteEntity方法,因为,前者,前面有@TransactionalMethod,故,为了减少对代码的影响,重写deleteEntity方法。

于是,在PersonRepository中,重写方法如下:

@Override
    public void deleteEntity(Object entity) {
        Person person = (Person)entity;
        crmManager.removeParty(person.getId());
    }

build代码,发现,并未删除。--------自己debug运行,看代码,检查了很久,都没有找出来原因,因为,明明是调用了removeParty方法,但是,一get请求,被删除的数据还在。

大概郁闷了一天吧,后面,实在没办法,只能找老大帮忙,经过老大的分析,select * from parties where id = 18476,查看数据库,发现,其实数据库并没有真正删除数据,而是将数据的字段isDeleted设置为1,表示该数据已被删除。因此,get请求的时候,这条被删除的数据还是会被查询出来。

也就是sunny总是删除不了的原因。即,所谓的软删除。

因此,再次查看get请求过程,sunny需要重写查询方法。

@Override
    public D findOne(String id, QuerySpec querySpec) {
        D dto = findDto(id);

        this.postFindOne(dto);

        return dto;
    }

public D findDto(String id) {
        Object entity = findEntity(id);
        D dto = createDto(entity);

        if (!this.getApiContext().isGetHttpMethod()) {
            updateDtoRelationship(entity, dto);
        }

        return dto;
    }

很明显,这里是通过findEntity(id)方法查询到entity,再通过entity创建dto的。因此,sunny需要重写findEntity方法,让数据库只查询出未被删除的数据。

PersonRepository重写findEntity(id)方法如下:

@Override
    protected Person findById(String id) {
        try {
            Person person =  crmManager.findPersonById(Integer.parseInt(id));
            if(!person.isDeleted()){
                return person;
            }else {
                return null;
            }
        } catch (PartyNotFoundException e) {
            throw new ResourceNotFoundException(e.getMessage());
        }
    }

再次build,发现,添加一条数据,然后删除,然后再去swagger中查询这一条数据,发现,真的被删除了,查不到了。

但是,如果是在swagger中查询所有的person,被删除的数据还是能被查询出来。因此,再次,仔细分析findAll的实现过程:

@Override
    public ResourceList<D> findAll(QuerySpec querySpec) {
        // Dependent or single instance
        if (this.getResourceConfiguration().isFindAllDisabled()) {
            throw new UnsupportedRequestException("Find all " + this.getResourceConfiguration().getResourceType() + " is not allowed.");
        }

        QueryParamsHelper helper = getQueryParamsHelper(querySpec);

        ResourceList<D> resourceList = findAll(helper);
        postFindAll(resourceList);

        return resourceList;
    }

    public ResourceList<D> findAll(QueryParamsHelper helper) {
        return query(helper);
    }

    @NotNull
    protected ApiResourceList<D> query(QueryParamsHelper helper) {
        HibernateQueryOptions hibernateQueryOptions = helper.buildHibernateQueryOptions(this.getEntityClass(), queryService);
        addInterceptor(hibernateQueryOptions);
        hibernateQueryOptions.setSelectFetchModeAttribute(this.getResourceConfiguration().getSelectFetchModeAttribute());

        QueryResult queryResult = getQueryResult(hibernateQueryOptions);
        helper.setTotalNumber(queryResult.getTotalNumber());

        List<D> resourceList = (List<D>) queryResult.getEntities().stream().map(this::createDto).collect(Collectors.toList());
        return new ApiResourceList<>(resourceList, helper);
    }

sunny意识到,应该要在getEntities的时候,对代码进行重写,也就是,对查询的entity进行条件过滤。但是,对于这行代码

List<D> resourceList = (List<D>) queryResult.getEntities().stream().map(this::createDto).collect(Collectors.toList());

真的是,无从下手,思考了很久,与luke讨论,最后找的simon再次分析,simon建议我去修改hibernate的查询条件,而不需要去重新写一个过滤方法。

于是,新的问题产生了,如何去查看项目的hibernate查询条件呢?----sunny找了很久很久,好无奈,没找到sql语句。

可能是hibernate我不太懂底层原理,总之,花了不少时间查找,就是没找到数据库的sql语句。---------------后期,等老大有时间,sunny再问清楚。

找老大咨询,我应该在哪里修改sql语句,自信查看父类AbstractRepository,最后,老大让我重写getInternalFilters。

 public List<FilterComponent> getInternalFilters() {
        return new ArrayList<>();
    }

按住ctrl,再点击getInternalFilters方法名,就可以找到其实现类AbstractHedgeFundProductRepository中实现了该方法:

@Override
    public List<FilterComponent> getInternalFilters() {
        List<FilterComponent> filterComponents =  new ArrayList<>();
        filterComponents.add(new FilterComponent(new FilterFieldDefinition(PRIVATE_EQUITY), FilterOperation.EQUALS, isPrivateEquity()));
        return filterComponents;
    }

该方法的功能是,给hibernate动态添加查询条件。模仿其代码,重写personRepository代码如下:

@Override
    public List<FilterComponent> getInternalFilters() {
        List<FilterComponent> filterComponents =  new ArrayList<>();
        filterComponents.add(new FilterComponent(new FilterFieldDefinition(DELETED), FilterOperation.EQUALS, false));
        return filterComponents;
    }

由于数据库的字段名是is_deleted,该方法需要传入与is_deleted相对应的entity的属性名,在

最简单的方法,双击shift,输入deleted,下方会有提示,点击进入ContactMessageSummaryEntity,找到如下代码:

 @Column(name = "is_deleted")
    private boolean deleted;

当然,这里只是为了方便理解,其实真正的查找字段名过程如下:

PersonRepository中:

@Override
    public void deleteEntity(Object entity) {
        Person person = (Person)entity;
        crmManager.removeParty(person.getId());
    }

点击removeParty,则

 @Override
    @TransactionalMethod
    public void removeParty(Integer partyId) {
        try {
            Party party = findPartyById(partyId);
            doDelete(party);
        } catch (PartyNotFoundException e) {
            logger.warn("removeParty() called on unknown partyId " + partyId, e);
        }
    }

点击doDeleted,则:

private void doDelete(Party party) {
        if (party.isDeletable()) {
            LinkUtil.softDeleteLinks(party.getLinks());
            party.delete();
            updateParty(party);
        } else {
            throw new IllegalArgumentException("Party " + party.getId() + " is not deletable; " + party.getReasonNotDeletable());
        }
    }

点击party.delete,则:

@Override
    public void delete() {
        setDeleted(true);
    }

点击setDeleted,则:

@Override
    public void setDeleted(boolean deleted) throws IllegalStateException {
        if (deleted) {
            setDeletedDate(new Date());
            contactMessageSummaries = new HashSet<>();
        } else {
            setDeletedDate(null);
        }
        this.deleted = deleted;
    }

注意,这一行代码就是关键:this.deleted = deleted。说明,属性的字段名就是,deleted。点击deleted,则:

private boolean deleted;

因此,下面的代码中,传入的删除字段名为deleted。

感谢luke和我一起找deleted字段。

最后,完整的代码如下:

@Singleton
public class PersonRepository extends AbstractRepository<PersonDto> {
    private static final String DELETED = "deleted";

    @Inject
    protected CrmManager crmManager;

    protected Person createEntity(PersonDto dto) {
        //暂时让contactSource定义为null,创建person后再塞值
       Person person = crmManager.createPerson(dto.getFirstName(),dto.getLastName(),null);
       return person;
    }

    @Override
    public void deleteEntity(Object entity) {
        Person person = (Person)entity;
        crmManager.removeParty(person.getId());
    }

    @Override
    protected Person findById(String id) {
        try {
            Person person =  crmManager.findPersonById(Integer.parseInt(id));
            if(!person.isDeleted()){
                return person;
            }else {
                return null;
            }
        } catch (PartyNotFoundException e) {
            throw new ResourceNotFoundException(e.getMessage());
        }
    }

    @Override
    public List<FilterComponent> getInternalFilters() {
        List<FilterComponent> filterComponents =  new ArrayList<>();
        filterComponents.add(new FilterComponent(new FilterFieldDefinition(DELETED), FilterOperation.EQUALS, false));
        return filterComponents;
    }

}

总结:

1.debug调试要熟练

2.代码运行过程以及原理要清楚,从内部分析,逐条执行,理解,思考后再写代码。

3.写代码的同时,要结合数据库一起查看结果。

4.不懂的要及时问老大,不要浪费过多的时间,因为这个项目太庞大了。


 

Person的delete请求--------详细过程的更多相关文章

  1. Asp.net页面生命周期详解任我行(3)-服务器处理请求详细过程

    前言 百度了一下才知道,传智的邹老师桃李满天下呀,我也是邹老师的粉丝,最开始学习页面生命周期的时候也是看了邹老师的视频. 本人是参考了以下前辈的作品,本文中也参合了本人心得,绝非有意盗版,旨在传播,最 ...

  2. Person.post请求------详细过程

    首先,在PersonRepository的父类中查找save方法,如下: @Override @TransactionalMethod public <S extends D> S sav ...

  3. 在浏览器中简单输入一个网址,解密其后发生的一切(http请求的详细过程)

    在浏览器中简单输入一个网址,解密其后发生的一切(http请求的详细过程) 原文链接:http://www.360doc.com/content/14/1117/10/16948208_42571794 ...

  4. 一个http请求的详细过程

    一个http请求的详细过程 我们来看当我们在浏览器输入http://www.mycompany.com:8080/mydir/index.html,幕后所发生的一切. 首先http是一个应用层的协议, ...

  5. WebApi接口传参不再困惑(4):传参详解 一、get请求 二、post请求 三、put请求 四、delete请求 五、总结

    前言:还记得刚使用WebApi那会儿,被它的传参机制折腾了好久,查阅了半天资料.如今,使用WebApi也有段时间了,今天就记录下API接口传参的一些方式方法,算是一个笔记,也希望能帮初学者少走弯路.本 ...

  6. HTTP请求响应过程 与HTTPS区别

    原文:HTTP请求响应过程 与HTTPS区别 HTTP协议学习笔记,基础,干货 HTTP协议 HTTP协议主要应用是在服务器和客户端之间,客户端接受超文本. 服务器按照一定规则,发送到客户端(一般是浏 ...

  7. IDEA搭建SSMM框架(详细过程)

    IDEA搭建SSMM框架(详细过程) 相关环境 Intellij IDEA Ultimate Tomcat JDK MySql 5.6(win32/win64) Maven (可使用Intellij ...

  8. HBase 1.2.6 完全分布式集群安装部署详细过程

    Apache HBase 是一个高可靠性.高性能.面向列.可伸缩的分布式存储系统,是NoSQL数据库,基于Google Bigtable思想的开源实现,可在廉价的PC Server上搭建大规模结构化存 ...

  9. 使用.NET 6开发TodoList应用(10)——实现DELETE请求以及HTTP请求幂等性

    系列导航及源代码 使用.NET 6开发TodoList应用文章索引 需求 先说明一下关于原本想要去更新的PATCH请求的文章,从目前试验的情况来看,如果是按照.NET 6的项目结构(即只使用一个Pro ...

随机推荐

  1. 关于nginx访问 静态文件 403 的错误

    例如 ngixn的配置的静态文件访问 如下: location /static { root /var/app/lxxxx/web; } 1.检查所有的文件有无读权限 chmod 644 -R 2.检 ...

  2. 70. Climbing Stairs Add to List

    You are climbing a stair case. It takes n steps to reach to the top. Each time you can either climb ...

  3. JSplitPane的简单实现

    import java.awt.Color; import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.J ...

  4. angular input=file ng-change事件

    首先 ng-change事件要与ng-model绑定  但是 当input 的  type=file时   ngchange事件是失效的  我们可以用图中的onchange事件去代替 其次 如果想在这 ...

  5. CF 36E Two Paths——欧拉路

    题目:http://codeforces.com/contest/36/problem/E 找出两条欧拉路覆盖无向图. 套上欧拉路模板.用过的边要记录. 注意 一个连通块.4个奇度数点 的情况是在两个 ...

  6. nginx提示Error: Too many open files的解决办法

    nginx提示:Too many open files这种错误问题的原因是因为linux文件系统最大可打开文件数为1024,而你的nginx中的error.log出现大量的Too many open ...

  7. 蓝桥杯 基础练习 BASIC-22 FJ的字符串

    基础练习 FJ的字符串   时间限制:1.0s   内存限制:512.0MB 问题描述 FJ在沙盘上写了这样一些字符串: A1 = “A” A2 = “ABA” A3 = “ABACABA” A4 = ...

  8. Tex 括号的反思

    在Tex中,左双引号是“,右双引号是”,输入一篇包含双引号的文章,你的任务是把它转换成Tex的格式. 样例输入: “To be or not to be,”quoth the Bard,"t ...

  9. java代码异常捕获throws抛出异常

    总结:Throwable 是所以异常的父类.error和Exception是继承它的类 Exception: 这类异常一般是外部错误,例如试图从文件尾后读取数据等,这并不是程序本身的错误,而是在应用环 ...

  10. AllowsTransparency和WebBrowser兼容性问题解决方案

    AllowsTransparency和System.Windows.Controls.WebBrowser兼容性问题,能看这篇文章,所以原因也不用多说:最根本的就是因为MS对win32底层的WebBr ...