第三个任务

第三个任务

任务如下:


查找源文件:

然后就是找到这个功能按钮所对应的源文件:



打开源文件:

在eclipse中搜索ImpactAnalysisImportProcessor可找到ImpactAnalysisImportProcessor.java文件,这就是该按钮对应功能的源文件。

开始测试:

首先将pms上面的附件下载下来,然后运行本地测试系统,导入文件测试,并跟着代码debug了一遍,可是没发现任何错误,也能直接生成result文件,并没有存在空指针错误。


于是找到了标哥,标哥说这个问题是发生在生产环境下的,要在生产环境才看的到问题,给了我一个账号,登录生产环境,果然看到了空指针错误:


看到了报错的行数,就开始在java源文件里面看对应的代码。

可是出错的源文件在本地测试环境一直没有任何问题,在生产环境又报错,而且也没有办法对生产环境进行debug,这就是这一次任务最难的点。把整一个源文件看了一遍,也没有发现什么毛病,于是标哥叫我安装一下数据库,在数据库里面看看能不能做文章。于是就开始了安装oracle跟plsql的路。

安装Oracle与plsql

​ 由于我笔记本之前安装过Oracle,就想直接试试能不能用plsql直接连接上,可是试了好多次都不行,只好在标哥那里拿来了相同版本的Oracle以及plsql,把原来的全部卸载掉重新来。

下面是彻底卸载Oracle的方法:https://jingyan.baidu.com/article/922554468d4e6b851648f4e3.html

plsql安装方法很简单,只需要一直点击下一步就可以了。

然后就是安装Oracle:

安装包


在这个安装界面选择第二个,然后一直下一步即可。

环境变量

安装Oracle之后需要配置环境变量ORACLE_HOME和TNS_ADMIN环境变量:(在这里被坑了好久,一点要配置好环境变量,路径要对



然后打开plsql:


点击取消按钮进入主界面:


点击工具->首选项:


在红框位置配置好两个路径,然后重启plsql。

可是重启之后发现没有读取到远程数据库,一看是因为还没有替换tnsnames.ora文件,于是在标哥那里拿来了这个文件,替换掉D:\app\Simple_Y\product\11.2.0\client_1\network\admin目录下的tnsnames.ora文件,重启plsql,就可以读取到远程数据库了。

数据库连接

这时候在eclipse运行系统,然后导入excel文件解析,查看控制台消息,可以得出是哪一个数据库用户:


然后查看inventory_main项目的pom.xml文件


可以看到对应的数据库用户和密码。然后就用这个账户登录plsql:


连接上数据库之后(记得断vpn),点击下面的小按钮:


选择新建sql窗口,然后就可以对表进行查询了。

查找问题

下面的问题就是找到数据库中对应报错行的那个数据,而Java文件报错的行数为171行,找到对应的代码:

mapmo.put("A_DEVICE", aDevice==null?"":aDevice.getValue("STANDARD_NAME").toString());

意思也不难理解,就是在aDevice对象中获取key值为STANDARD_NAME的value值,放入mapmo对象中,但是debug到这里发现是读取得到对象的,并没有出现空指针错误,所以需要在数据库中找到这个数据,将它置为空,看看能不能出现空指针问题。然后标哥教了我底层元数据api操作数据库的原理:

          QueryCriteria qc = new QueryCriteria("SERVICE");
          qc.addAssembleFragment("[SERVICE_END_A_DEVICE][SERVICE_END_Z_DEVICE]");
          qc.addExpression(QueryExpressionUtil.equals("ID", servId));
          List<MetaObject> services = metaService.query(qc).getList();
          //上面的就是公司操作数据库的api,一开始一直看不懂
          //下面解释具体的意思:
  
          --QueryCriteria qc = new QueryCriteria("SERVICE");
          select * from xm_entityspec m where m.code = 'SERVICE';

上面这两句是等同的,在查询结果我们可以看到service对应的表名:


下面的是等同的:

  
  --qc.addAssembleFragment("[SERVICE_END_A_DEVICE][SERVICE_END_Z_DEVICE]");
  select * from xm_relationspec m where m.code = 'SERVICE_END_A_DEVICE';
  select * from xm_relationspec m where m.code = 'SERVICE_END_Z_DEVICE';


由于我们不知道两个ID分别是对应哪一个,所以需要下面的查询语句来确定:

select * from xm_entityspec m where m.id in (2310000000,1020000000);

在xm_entityspec--实体规格描述表中查询它们分别对应什么:


可以看到两个ID分别对应设备和产品服务以及他们的数据表。

接下来就是:

  
  --根据servid查到service实体的数据
  select m.a_device_id,m.* from RM_SERVICE m where m.id = '441020000000001125355060' ;
  --根据service实体数据的a_device_id查询device实体的数据
  select m.standard_name,m.* from CM_DEVICE m where m.id = 441020000000001083663191;

到这里就可以找到STANDARD_NAME属性的值了,在这里将STANDARD_NAME属性置为空,然后运行系统看看会不会报空指针错误。

  
  --置空
  update CM_DEVICE set standard_name = '' where id = 441020000000001163583121;
  --查询结果
  select m.standard_name,m.* from CM_DEVICE m where m.id = 441020000000001083663191;


ok,成功置空了,然后重新启动系统,清空浏览器缓存,重启数据库,终于如愿以偿地看到了空指针异常。

解决问题

看来已经找到了问题了,让我们再来看看报错的代码行:

  
  mapmo.put("A_DEVICE", aDevice==null?"":aDevice.getValue("STANDARD_NAME").toString());

当aDevice.getValue("STANDARD_NAME")不存在的时候,系统就会发生空指针异常,于是我百度了一下:

map 允许null键null值 你的value引入的是一个变量吧 这个变量获取到的值为空 会报空指针异常,可以对这个变量做一个判断不就行了

是的,问题终于有突破口了,然后就对这一行进行重写:

  
  mapmo.put("A_DEVICE", aDevice==null?"":aDevice.getValue("STANDARD_NAME").toString());
  ->
  if(aDevice!=null && aDevice.getValue("STANDARD_NAME")!=null){
              mapmo.put("A_DEVICE", aDevice.getValue("STANDARD_NAME").toString());
          }

加入对aDevice.getValue("STANDARD_NAME")的判空处理,重新运行系统,完美通过,终于把这个问题解决了。

然后svn同步本地代码,更新代码,提交自己的修改,在pms网站上提交补丁,问题解决。


这次的问题主要是在数据库方面遇到了不少阻碍,对Oracle数据库无从下手,要看懂元数据操作的api,根据其对应的select语句找到想要的数据,才能开始动手。

下面是标哥说的比较重要的三个表:

xm_entityspec --实体规格描述表xm_relationspec --实体规格关系描述表xm_entitydescriptor --描述实体规格对应哪些数据表,以及数据表有哪些属性底层元数据api的实现,是基于上面3个表的,要了解元数据api,上面3个表是比较重要的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值