最近把Spring Boot的版本升級到了3.3.5,突然發現一個問題:當使用Spring Data JPA自動生成表的時候,所產生的列順序與Entity類中的變數順序不一致了。比如,有一個下面這樣的Entity:
@Data
@Entity(name = "t_config")
@EntityListeners(AuditingEntityListener.class)
public class Config {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(length = 20)
private String itemKey;
@Column(length = 200)
private String itemValue;
@Column(length = 200)
private String itemDesc;
@CreatedDate
private Date createTime;
@LastModifiedDate
private Date modifyTime;
}
實際自動建立出來的是這樣的:
自動建立的表結構中各個列與Entity類中的變數順序不一致。其實該問題是一個老生常談的問題了,在DD這次升級的工程裡是有做過解決方案的。只是升級了Spring Boot版本之後,之前的解決方案失效了。
搜尋了一番,同時還問了一下AI,發現給出的方案還都是老的解決方案,所以今天特別寫一篇來記錄下新版本之下,要如何解決這個問題。如果您剛好遇到類似的問題,可以參考本文來解決。
老版本解決方案
新老版本的解決思路是類似的,都是替換Hibernate的實現,下面是老版本的解決步驟:
- 在工程中新建
org.hibernate.cfg
包 - 找到
hibernate-core
包下的org.hibernate.cfg
下的PropertyContainer
類,複製到本工程的org.hibernate.cfg
包下 - 把
PropertyContainer
類中定義的persistentAttributeMap
型別從TreeMap
修改為LinkedHashMap
新版本解決方案
雖然之前的方案失效了,但思路應該還是對的,所以第一反應是看看當前版本下的PropertyContainer
類,具體如下(省略了一些不重要的內容):
package org.hibernate.boot.model.internal;
//省略...
public class PropertyContainer {
private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, PropertyContainer.class.getName());
/**
* The class for which this container is created.
*/
private final XClass xClass;
private final XClass entityAtStake;
/**
* Holds the AccessType indicated for use at the class/container-level for cases where persistent attribute
* did not specify.
*/
private final AccessType classLevelAccessType;
private final List<XProperty> persistentAttributes;
//省略...
}
可以看到有兩個重要變化部分:
PropertyContainer
類的包名從org.hibernate.cfg
改到了org.hibernate.boot.model.internal
- 之前的
TreeMap<String XProperty> persistentAttributeMap
變數沒有了,但多了一個List<XProperty> persistentAttributes
。進一步觀察這個新變數的處理過程,可以看到如下邏輯:
所以,新版的方案就以下兩個步驟:
- 在工程中新建
org.hibernate.boot.model.internal
包 - 找到
hibernate-core
包下的org.hibernate.boot.model.internal
下的PropertyContainer
類,複製到本工程的org.hibernate.boot.model.internal
包下 - 把
PropertyContainer
類中,上面圖中紅色圈出部門定義的localAttributeMap = new TreeMap<>();
修改為localAttributeMap = new LinkedHashMap<>();
到這裡,在新版本中的這個問題就解決了。如果你也遇到了類似的問題,希望本文對你有所幫助。另外,歡迎加入我們的Spring技術交流群,參與交流與討論,更好的學習與進步!
歡迎關注我的公眾號:程式猿DD。第一時間瞭解前沿行業訊息、分享深度技術乾貨、獲取優質學習資源