我有一個案例,我將一個大jsonb欄位保存到 PostGres 表中,但在獲取物體時不想讀取它;如果我真的拿到它,我的服務就會OOM。更好的設計可能是將其分成 1 對 1 表,但我現在不能這樣做。
為了懇求這不是一個重復的問題,這是我的一些研究:
- 我無法標記該列
LAZY,因為我有一個簡單的列而不是連接` JPA/Hibernate 只寫欄位,沒有讀取 - 我在這個建議中嘗試了空設定器,這是有道理的 - 但它似乎仍然可以讀取該列并且我 OOM:https ://www.zizka.ch/pages/programming/java/hibernate/hibernate-write-only.html
- 我還嘗試在
@Data課堂上完全省略 setter:在 Lombok 中省略一個 Setter/Getter
因此,我看不到該欄位,但似乎無法阻止它在后臺被讀入記憶體。似乎在 JPA 或 Hibernate 中必須有一些簡單的設定才能從讀取中排除列。在我嘗試創建一個復雜的存盤庫層次結構只是為了看看它是否有效之前,我想我會在這里問一下,以防萬一我走運。
提前致謝!
uj5u.com熱心網友回復:
延遲加載屬性
Hibernate可以延遲加載屬性,但需要啟用位元組碼增強功能:
首先,您需要將屬性設定
hibernate.enhancer.enableLazyInitialization為 true然后您可以使用 注釋該欄位
@Basic( fetch = FetchType.LAZY )。這是檔案中的示例:@Entity public class Customer { @Id private Integer id; private String name; @Basic( fetch = FetchType.LAZY ) private UUID accountsPayableXrefId; @Lob @Basic( fetch = FetchType.LAZY ) @LazyGroup( "lobs" ) private Blob image; //Getters and setters are omitted for brevity }
您還可以通過Hibernate ORM gradle 插件啟用此功能
命名本機查詢
您也可以決定不映射它并使用命名的本機查詢保存/讀取它。對于單個屬性,這似乎是一個很好的權衡——它只需要一個額外的查詢來保存 json。
例子:
@Entity
@Table(name = "MyEntity_table")
@NamedNativeQuery(
name = "write_json",
query = "update MyEntity_table set json_column = :json where id = :id")
@NamedNativeQuery(
name = "read_json",
query = "select json_column from MyEntity_table where id = :id")
class MyEntity {
....
}
Long id = ...
String jsonString = ...
session.createNamedQuery( "write_json" )
.setParameter( "id", id )
.setParameter( "json", jsonString )
.executeUpdate();
jsonString = (String)session.createNamedQuery( "read_json" )
.setParameter( "id", id )
.getSingleResult();
在這種情況下,模式生成不會創建列,因此您需要手動添加它(考慮到有更好的工具來更新生產中的模式,這沒什么大不了的)。
映射超類
您還可以讓兩個物體擴展同一個超類(這樣您就不必復制屬性)。他們必須更新同一張表:
@MappedSuperclass
class MyEntity {
@Id
Long id;
String name
...
}
@Entity
@Table(name = "MyEntity_table")
class MyEntityWriter extends MyEntity {
String json
}
@Entity
@Table(name = "MyEntity_table")
class MyEntityReader extends MyEntity {
// No field is necessary here
}
現在您可以MyEntityWriter用于保存所有值并MyEntityReader僅加載您需要的值。
如果您嘗試創建表,我認為您將在模式生成方面遇到一些問題,因為只會創建這兩個表中的一個:
- 如果
MyEntityWriter是創建的第一個表,那么沒問題 - 如果創建
MyEntityWriter了第二個表,則查詢將失敗,因為該表已經存在并且不會創建附加列。
不過我還沒有測驗過這個解決方案,可能有一些我沒有想到的東西。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/493986.html
