修改Hibernate源碼實現建表時字段和Entity里定義的fields順序一致 -


Hibernate(至截稿時最新版本為4.1.3.Final)自動建表的表字段順序總是隨機的,之前我們總是自己寫語句建好表,再使用Hibernate進行增刪改查。始終是有點不方便。 
最近看了下源碼,發現很多地方都是使用LinkedHashMap或者是List來傳輸Entity里面的fields,覺得Hibernate應該是考慮到使用Entity里面定義的fields的順序來實現建表語句里的表字段順序的。 
於是一步步跟蹤下去,終於在一個地方發現了一個問題:org.hibernate.cfg.PropertyContainer在取fields的時候是使用TreeMap來保存的,於是試着改了下,將這個里面的所有TreeMap改成了LinkedHashMap,編譯通過,打包,測試。 
終於,我們期待已久的結果出來了:建表語句里面的字段順序和Entity里面的fields的順序一致了。 

以下附上源碼和修改后的代碼: 
源碼: 

private final TreeMap<String, XProperty> fieldAccessMap; 

private final TreeMap<String, XProperty> propertyAccessMap; 

private TreeMap<String, XProperty> initProperties(AccessType access) { 
if ( !( AccessType.PROPERTY.equals( access ) || AccessType.FIELD.equals( access ) ) ) { 
throw new IllegalArgumentException( "Access type has to be AccessType.FIELD or AccessType.Property" ); 


// 其實通過以下注釋也可以發現是Hibernate自己的一個失誤 
//order so that property are used in the same order when binding native query 
TreeMap<String, XProperty> propertiesMap = new TreeMap<String, XProperty>(); 
List<XProperty> properties = xClass.getDeclaredProperties( access.getType() ); 
for ( XProperty property : properties ) { 
if ( mustBeSkipped( property ) ) { 
continue; 

propertiesMap.put( property.getName(), property ); 

return propertiesMap; 


修改后的代碼 

private final LinkedHashMap<String, XProperty> fieldAccessMap; 

private final LinkedHashMap<String, XProperty> propertyAccessMap; 

private LinkedHashMap<String, XProperty> initProperties(AccessType access) { 
if ( !( AccessType.PROPERTY.equals( access ) || AccessType.FIELD.equals( access ) ) ) { 
throw new IllegalArgumentException( "Access type has to be AccessType.FIELD or AccessType.Property" ); 


//order so that property are used in the same order when binding native query 
LinkedHashMap<String, XProperty> propertiesMap = new LinkedHashMap<String, XProperty>(); 
List<XProperty> properties = xClass.getDeclaredProperties( access.getType() ); 
for ( XProperty property : properties ) { 
if ( mustBeSkipped( property ) ) { 
continue; 

propertiesMap.put( property.getName(), property ); 

return propertiesMap; 


PS:通過以下代碼可以測試建表時的語句: 
public static void main(String[] args) { 
    Configuration cfg = new Configuration().configure(); 
    SchemaExport export = new SchemaExport(cfg); 
    export.create(true, true); 
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM