首先,数据库的增删改查都是在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. PNG24在ie6下的完美解决方法!(DD_belatedPNG)

    原网址:http://www.zjgsq.com/1629.html 之前写过一篇<js+css滤镜设置解决PNG24在IE6下显示问题> 解决方法不是很完美,使用起来也比较麻烦. DD_ ...

  2. THUSC 2017 大魔法师

    一个序列,每个物品有三个权值 $A,B,C$ 要求维护: 1.区间 $A_i+=B_i$ 2.区间 $B_i+=C_i$ 3.区间 $C_i+=A_i$ 4.区间 $A_i+=v$ 5.区间 $B_i ...

  3. 【2】HashMap

    http://www.cnblogs.com/xwdreamer/archive/2012/06/03/2532832.html 一:java的数据结构 在Java编程语言中,最基本的结构就是两种,一 ...

  4. 使用sort&awk实现文件内容块排序

    源文件为: [root@luo5 wangxx]# cat -v luo.txt J LuoSoutth jfsaNanjing,china Y ZhangVictory UniversityNejf ...

  5. ERR_PTR PTR_ERR IS_ERR ERROR

    在linux-x.xx/include/uapi/asm-generic/errno-base.h和errno.h里分别定义了返回错误的信息. errno-base.h: #ifndef _ASM_G ...

  6. 导入镜像后,容器内httpd起不来

    导入镜像后发现bash进程为1 与之前apache启动的进程冲突了 解决办法:删除apache进程号,通过apachectl重启apache进程

  7. [更新中]【South使用总结】django开发中使用South进行数据库迁移

    Django开发中使用South进行数据库迁移的使用总结 South的详细资料可产看官方文档http://south.readthedocs.org/en/latest South安装配置 pip i ...

  8. 2015.12.24(圣诞节) 解决Oralce数据库将具有相同属性的多行合并为一行的简单方法多年想要wmsys.wm_concat

    用到Oralce10g以后增加的函数wmsys.wm_concat 例如这张表的有两个字段,要按airport_id合并成两行可用sql语句 select airport_id,   wmsys.wm ...

  9. 问题:table 可否实现对角线;结果:用div+css模拟表格对角线

    首先声明: 这只是探讨一种CSS模拟表格对角线的用法,实际在工作中可能觉得这样做有点小题大作,这不是本主题讨论的重点.如果对此深以为然的朋友,请一笑过之... 有时在插入文档时,要用到表格对角线,常见 ...

  10. C语言学习笔记--#和##操作符

    1. #运算符 (1)#运算符用于在预处理期将宏的参数转换为字符串 (2)#的转换作用是在预处理期完成的,因此只在宏定义中有效,即其他地方不能用#运算符 (3)用法:#define STRING(x) ...