Sonar煩惱
??今天把一個業(yè)務項目上傳到了SonarQube,提示代碼重復率7.5%蚓庭,默認的標準是5%猪瞬,超標了。
??本來因為只是個用作數(shù)據(jù)收集的新項目富岳,使用到的表比較少蛔糯,而表的基本字段有重復,使用了Spring-boot-data-jpa生成的model對象屬性便有部分重復窖式。
??本來是個小事情蚁飒,置之不理就好,但是萝喘。淮逻。。
??嘗試使用extends對model進行繼承結構梳理阁簸,A extends B爬早,嘗試編譯,報錯:【子類builder不能覆蓋父類】启妹。因為在model上使用了lombok的builder注解筛严,創(chuàng)建的builder方法不能覆蓋。
??由于builder結構的便利性饶米,在業(yè)務代碼中多次使用了類似A.builder().aaa().bbb().build()這種寫法桨啃,不忍舍棄车胡,嘗試google解決,得到@SuperBuilder注解照瘾,在最新的lombok18上有提供吨拍,趕緊更改依賴包版本,更改注解測試网杆,按文檔說明父類子類都使用@SuperBuilder標注羹饰,測試方法中嘗試B.builder(),未能獲得。使用compile編譯碳却,觀察生成class文件队秩,的確已經(jīng)存在使用了泛型并且支持繼承關系的builder對象和builder()方法,為什么不成功呢昼浦?
??猜測是lombok插件的問題馍资,打開idea的插件管理器,查看lombok plugin支持注解列表說明关噪,果然沒有@SuperBuilder鸟蟹,看來只支持到1.16的lombok版本。嘗試雙擊lombok.jar安裝插件使兔,發(fā)現(xiàn)只支持eclipse核心ide建钥,想讓我換開發(fā)工具?不存在的~ 算了放棄放棄虐沥。
??嘗試@Accessors注解熊经,加上chain=true之后,生成的setter方法會將自身返回欲险,看起來很好用镐依,然而子類的示例,調(diào)用了父類屬性的setter之后天试,返回的對象就變成父類了槐壳,需要聲明下類型轉(zhuǎn)換,略麻煩喜每。
??還是回到@Builder注解做文章务唐,觀察注解屬性列表,發(fā)現(xiàn)builder方法名灼卢、類名绍哎、build方法名来农,都是可以更改的鞋真!嘗試加上(builderMethodName = "aesbuilder")進行編譯,通過了沃于!觀察生成的builder方法涩咖,已然變成了aesbuilder()海诲,very Good。
??然而檩互,同時也發(fā)現(xiàn)了一個嚴重問題特幔,builder返回的Builder類,支持的屬性設置闸昨,只有子類的蚯斯,而繼承自父類的屬性并不在里面。而事實上饵较,@SuperBuilder正是用來解決這一問題的拍嵌,然而并沒有可用的idea插件。循诉。横辆。
??google發(fā)現(xiàn)了一個大神給的方案,@Builder聲明在構造方法上茄猫,而構造方法參數(shù)里狈蚤,把需要用到的屬性逐個聲明一遍,雖然略笨重划纽,不過看似可行脆侮,于是改造代碼為
@Builder(builderMethodName = "aesbuilder")
public ActivityEventStatistic(final Long id, final String pageCode, final String eventCode, final Integer pv, final Integer uv, final Integer timeHour,final String activityCode){
super(id, pageCode, eventCode, pv, uv, timeHour);
this.activityCode = activityCode;
}
public static void main(String[] args) {
ActivityEventStatistic.aesbuilder().id(123l).pageCode("test").build();
}
it works! wow~
??OK,編譯通過勇劣,進入測試階段他嚷,test case跑起來,然后duang~ 又遇到問題了芭毙!提示執(zhí)行的查詢sql筋蓖,屬性未找到。分析之后發(fā)現(xiàn)退敦,由于model使用了繼承粘咖,而沒有顯示聲明Inheritance策略,所以jpa使用了默認的策略SINGLE_TABLE侈百,也就是父類子類公用了一張表瓮下,再加上并沒有聲明哪些屬性屬于子類,所以就報錯了钝域。
??另外讽坏,很顯然,我這種情況并不能使用SINGLE_TABLE例证,而應該使用TABLE_PER_CLASS路呜。ok,在model上加上@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS),再次run test胀葱,報錯如下:
nested exception is org.hibernate.MappingException: Cannot use identity column key generation with <union-subclass> mapping for: com.quzeng.idss.domain.PageStatistic
??查找問題后得知漠秋,在model上使用了繼承關系后,就不能使用自動主鍵策略了抵屿,而只能用GenerationType.TABLE才可以庆锦。。轧葛。吐血搂抒。。尿扯。
??ok燕耿,創(chuàng)建表hibernate_sequences,添加字段sequence_name,next_val姜胖,嘗試run test誉帅,總算成功了。右莱。蚜锨。
??但是,面臨的問題還是有的慢蜓,首當其沖的是亚再,GenerationType.TABLE被人詬病因為每次請求時的鎖機制造成的性能嚴重影響的問題,參考:why-you-should-never-use-the-table-identifier-generator-with-jpa-and-hibernate晨抡,另外一個氛悬,是我要對每個表創(chuàng)建ID生成器,指定序列器名稱耘柱、范圍如捅,以及hibernate_sequences 表中要添加好相應記錄,還要將這些改動腳本整理下來调煎,告知DBA镜遣,說是因為一個蛋疼的重復率指標導致的主鍵策略改動,還不知道會不會被拒絕掉士袄。悲关。。
??哎娄柳,你說我瞎折騰什么呢寓辱。??