亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

在控制器范圍之外獲取惰性集合而不調用 getter

在控制器范圍之外獲取惰性集合而不調用 getter

慕桂英546537 2022-06-08 17:25:40
我有一個帶有 Spring JPA 的休眠實現的 Spring Boot Web 應用程序。我使用連接列注釋在我的實體之間建立了一對多關系。為此,技術實體有一個成員,即 List。我已將此列表標記為延遲初始化。一切都很好,但是一旦控件移出控制器,hibernate 就會在沒有調用它的情況下觸發對惰性集合(List)的調用。這會導致加載網頁的巨大延遲。不知道為什么休眠會在控制器范圍之外觸發延遲集合。我嘗試過使用 Hibernate.initialize 和 Maven 字節碼增強插件,但似乎沒有任何效果。請幫忙實體@Entity@Table(name="EmergentTechnologies")public class EmergentTechnology implements Serializable {    private static final long serialVersionUID = 1L;    @Id    @GeneratedValue(strategy=GenerationType.AUTO)    @Column(name="ID")    private int id;    @OneToMany    @JoinColumn(name="ETID")    @Basic(fetch = FetchType.LAZY)    private List<Artifact> artifacts;@Entity@Table(name="Artifacts")public class Artifact implements Serializable {    private static final long serialVersionUID = 1L;    @Id    @GeneratedValue(strategy=GenerationType.AUTO)    @Column(name="ID")    private int id;    @Column(name="Analyst")    private String analyst;    @Column(name="ArtifactType")    private String artifactType;應用程序屬性spring.mvc.favicon.enabled=falselogging.level.com.boeing.etl=INFOspring.datasource.driver-class-name=com.microsoft.sqlserver.jdbc.SQLServerDriverspring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImplspring.jpa.generate-ddl=falsespring.jpa.show-sql=truespring.jpa.hibernate.dialect=org.hibernate.dialect.SQLServer2012Dialect
查看完整描述

2 回答

?
SMILET

TA貢獻1796條經驗 獲得超4個贊

回答之前的一件事:不要將實體作為休息服務的響應返回,因為您將服務的消費者耦合到您的數據庫,因此是一種不好的做法。

現在答案是:當您的控制器返回一個包含在 ResponseEntity 中的列表時。@ResponseBody 注解的意思是方法的返回值將構成 HTTP 響應的正文。由于響應中不允許有 Java 對象,因此必須將它們序列化為適合 REST 應用程序的格式,即 JSON 或 XML(這將取決于 RequestMapping 注釋的生產屬性的值,以及客戶端接受的內容類型) . 由于這個序列化過程,來自 EmergentTechnology 對象(由 Hibernate 管理,因此它們被代理)的 getter 方法將被調用。此調用將導致獲取工件列表。

因此,您要做的是將您的實體映射到服務 EmergingTechLibService (我推薦MapStruct)中的一個 VO (避免一對),避免調用工件的 getter


查看完整回答
反對 回復 2022-06-08
?
慕的地10843

TA貢獻1785條經驗 獲得超8個贊

您似乎遇到了 1+N 問題。您可以讓休眠在一個查詢中加載所有數據。為此,您可以將 fetch join 與您的條件一起使用。


@Override

public List<EmergentTechnology> getAllArtifactsById(int emergentTechId) {

    logger.info("Enter getEmergentTechnologies");

    CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();

    CriteriaQuery<EmergentTechnology> criteriaQuery = criteriaBuilder.createQuery(EmergentTechnology.class);

    Root<EmergentTechnology> root = criteriaQuery.from(EmergentTechnology.class);


    // NEW CODE 

    root.fetch("artifacts", JoinType.INNER);


    criteriaQuery.select(root);

    criteriaQuery.where(criteriaBuilder.equal(root.<Integer>get("id"), emergentTechId));

    List<EmergentTechnology> emergingTechnologies = entityManager.createQuery(criteriaQuery).getResultList();

    logger.info("Exit getEmergentTechnologies");

    return emergingTechnologies;

}

讓休眠通過一個查詢獲取所有數據的另一種選擇是使用命名實體圖。


雖然我不確定這是否會解決您的所有問題,但您仍然應該會看到性能提升。


此外,根據您的數據的性質(在我看來,這是一組不會很大并且不會發生太大或經常變化的信息),您可以充分利用彈簧緩存,這將非常適合您的用例.


另一種選擇是使用休眠查詢緩存。


查看完整回答
反對 回復 2022-06-08
  • 2 回答
  • 0 關注
  • 121 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號