作者cyclone350 (老子我最神)
看板java
标题[问题] Java 反射机制於 compile 时检查
时间Sun Sep 27 18:38:18 2015
大家好
java 专案里面多多少少会使用到反射机制写程式
比较常见的像是 criteria ...
例如程式码
final CriteriaQuery<User> q = cb.createQuery(User.class);
final Root<User> users = q.from(User.class);
final Predicate condition = cb.equal(users.get("privilegeLevel"), 5);
q.select(users)
.where(condition)
.orderBy(cb.asc(users.get("userId")));
其中 privilegeLevel 会直接对应到 entity 的 field
若是 entity 修改 privilegeLevel 栏位名称,在 compile 阶段并不会检查到
而到真正 runtime 时才会发现错误。
想请问有无方法可以在 compile 时可以检查的 ?
(ide plugin 或 build tool plugin 都可)
除了 compile 检查以下我目前知道以下几种解法
1. 让所有开发工程师都明白这件事情,在修改程式码时会更小心注意。
2. 使用
http://goo.gl/zhhdLh 文章的方法。
3. 修改程式有发生错误的风险,所以不要修改程式。
方法 1... , 可让发生错误降低,但无法保证不会发生...
方法 2... , 可以杜绝错误,但个人有点不爱,因为除了 Criteria 外还有 hql,
需要把整个专案(跟DB有关)翻掉重写,我们专案没有 test 流程,
若是人工修改人工测试,会消耗非常巨量的时间。
方法 3... , 最安全的做法,但我觉得同时也是最糟糕的做法。
三个方法要选的话我会选 1
不过目前想到最完美的方法就是有现成的 compile 时段就可以检查的,
想请问各位前辈有无这种工具或套件,若没有的话,你们专案是如何解决
这类问题的 !?
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 123.193.192.133
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/java/M.1443350301.A.F12.html
1F:推 NullLife: 我觉得用ORM来说 改field的时候 就相当於下DDL改column 09/27 20:27
2F:→ NullLife: 名称 也就等於你相关的SQL语句都必须修改 09/27 20:27
3F:→ NullLife: 除非用mapping啦,以JPA来说就有annotation可以不耦合 09/27 20:29
4F:→ NullLife: field名称 所以我觉得重点还是在为什麽要去修改名称勒? 09/27 20:30
并非为了修改名称而修改名称,在某些情况下可能会无意的修改,例如你要把
不同的专案的某些功能整合在一起,而他们有共用的 Entity,但是 Entity 又
不一致,在整合程式时若是在没有警觉的情况下是有可能犯下这种错误。
Ex: 专案1 的 entity field name = iAmAField
专案2 的 entity field name = iAmAfield
方法 1 就是告知大家有这种情况,下次修改或整合程式时必须注意这种状况。
是想说如果有现成的工具帮忙检查会更好 XD。
※ 编辑: cyclone350 (123.193.192.133), 09/27/2015 20:40:33
5F:推 NullLife: SOGA 工具我是不晓得 但用Eclipse的时候 在字串那边 09/27 20:46
6F:→ NullLife: 就可以用ctrl点看看有无link 我觉得这已经够方便了 XD 09/27 20:47
7F:→ qrtt1: 觉得写 unit test 才是比较好的方法。 09/27 20:51
8F:→ wuliou: 我想你还是写unit test吧 09/27 22:02
9F:→ bitlife: 有阳春工具可解决本篇问题,但对写在sql内的field/table名 09/28 10:28
10F:→ bitlife: 称修改就没用,方法是把所有table及fields在coding时期从 09/28 10:28
11F:→ bitlife: db读出来,每个table做成一个以table name为名的class,然 09/28 10:29
12F:→ bitlife: 後所有该table的栏位成为该对应class的final static字串 09/28 10:29
13F:→ bitlife: 假设需要A表格的b栏位,程式就写A.b 09/28 10:30
14F:→ bitlife: 当table有变动,就重跑一次抓表格/栏位工具,哪里编不过就 09/28 10:31
15F:→ bitlife: 知道了 09/28 10:31
16F:→ swpoker: 这种就只能执行时才能知道~所以unit test吧 09/30 10:16
18F:→ marsyang1: generate-jpa-2-0-metamodel 10/01 18:33
19F:→ marsyang1: 参考参考,我自己是用spring data,为了整合性使用quer 10/01 18:35
20F:→ marsyang1: y dsl,但做法都差不多。 10/01 18:35
21F:推 marsyang1: 组query会是用metamodel的class,不会用反射 10/01 18:38
感谢大家回应 :)
先回 unit test 的部分,其实一直有在补啦 ><,因为这是一个蛮有历史的专案,
交给我的时候... 有点乱就是了...
所以一有空闲时间就会
1. 看程式补文件
2. 重构
3. 补 unit test
不过这一部分老板不正视就很难腾出时间。
spring data 的方案花的成本跟原先 2 是一样的。
个人也觉得 spring data 很好用,之前开发新专案就是用 spring data。
目前看来应该只能方法1 跟补足 unit test 并行了
※ 编辑: cyclone350 (123.193.192.133), 10/04/2015 14:45:36
22F:→ adrianshum: 我有想过用类似 Mockito 的做法写Util 去 runtime 10/08 09:29
23F:→ adrianshum: 生成 method name e.g.nameOf(c(Foo.class).method()) 10/08 09:30
24F:→ adrianshum: 不过因为某些原因没有动手做。可以考虑 10/08 09:31
25F:→ adrianshum: 不过 property name/variable name 真的有点难搞 10/08 09:32
26F:→ adrianshum: QueryDSL 应该是暂时最可行的做法了 10/08 09:32