首先,数据库的增删改查都是在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.不懂的要及时问老大,不要浪费过多的时间,因为这个项目太庞大了。


 

最新文章

  1. ASP.NET Mvc实用框架(一)Ioc、仓储模式和单元工作模式
  2. 【GWAS文献】基于GWAS与群体进化分析挖掘大豆相关基因
  3. myeclipse9中导入的jquery文件报错(出现红叉叉,提示语法错误)
  4. 用UNIX消息队列实现IPC(以ATM为例)
  5. (转)Java DES 与Base64
  6. java 切换
  7. 多台服务器最好加上相同的machineKey
  8. 在自己的网站上实现QQ授权登录
  9. ACM组队安排
  10. frame嵌套的学习
  11. Git 和 Github的关系
  12. Elastarchsearch安装搭建(一)
  13. android 图片拍照图片旋转的处理方式
  14. Web安全概述
  15. mysql Using filesort 索引不可用问题
  16. Unity3d之-使用BMFont制作美术字体
  17. http 协议_DNS_域名解析 DNS 服务器_内容分发网络 CDN_缓存机制_HTML5 浏览器存储技术_cookie_sessionStorage_localStorage
  18. win10操作系统上,wireshark抓取https。
  19. Python框架学习之用Flask创建一个简单项目
  20. linux 下安装vscode

热门文章

  1. LKDBHelper Sqlite操作数据库
  2. UVA - 242 Stamps and Envelope Size (完全背包+bitset)
  3. 畅通工程(自己写的BFS,但后面想了下并查集更好更快)
  4. LeetCode 323. Number of Connected Components in an Undirected Graph
  5. LeetCode Shopping Offers
  6. loj 6485 LJJ学二项式定理 —— 单位根反演
  7. 两种设置WebLogic启动内存的方法
  8. 利用TaskScheduler处理Queue、Stack等类型的操作队列(生产者消费者场景)
  9. eclipse -- propedit 安装.
  10. java中的死锁现象