2014-09-10 57 views
1

對於常見問題,抱歉,在開發一個寧靜的AngularJS應用程序時,是否還有一種仍然使用JPA延遲加載實體的方法。針對JPA延遲加載Rest/AngularJS的最佳方法

在舊的JSF日子裏,當一個支持bean訪問列表時,它們都可以工作。

我正在使用EclipseLink和Spring Data,以及澤西島的寧靜端點。

問候

回答

0

一般來說,你不得不觸發之前的EntityManager實體的延遲加載請求的生命週期中被關閉。

爲此,您可以使用「在視圖中打開EntityManager」模式。 Spring提供您可以申請的FilterOpenEntityManagerInViewFilter(請閱讀文檔:http://docs.spring.io/spring/docs/4.1.0.RELEASE/javadoc-api/org/springframework/orm/jpa/support/OpenEntityManagerInViewFilter.html)。

或者,您可以在將JPA實體序列化爲JSON之前手動調用getMyLazyCollection()

+0

解決'getMyLazyCollection()'你是否表示在返回JSON之前整個實體將被解析爲服務器端? – bhantol 2014-09-22 19:28:01

+0

實體需要在服務器端的某個點解決。因此,如果您在此期間(通過過濾器)打開了EntityManager,或者在JSON序列化之前(如果您明確調用getter方法),那麼會在JSON序列化期間發生(遍歷對象圖)。當然,您可以將實體的懶集合標記爲不可序列化(通過Jackson2),然後再通過「@ JsonIgnore」再次調用服務器以獲取集合。不知道如何適合你的確切用例。 – 2014-09-23 20:27:30

0

我認爲最好的課程取決於以下幾點。

您是否能夠檢索完全解析的實體,即其所有 組件,而不會對性能產生負面影響?

如果答案是Yes那麼去解決完整的實體使用JPA獲取選項=渴望。我的答案是No。我會採用以下方法: -

1)將每個惰性JPA組件/關聯明確公開爲sub-resource

例如

@Entity 
    public class Employee { 
     @Id 
     private long id; 
     ... 
     @OneToOne(fetch=FetchType.LAZY) 
     @JoinColumn(name="ADDR_ID") 
     private Address homeAddress; 
     ... 
    } 
    @Entity 
    public class Address{ 
    } 

2)無論你是用`OpenEntityManagerInViewFilter`或隱含暴露服務作爲控制器(雖然你可以讓他們分開,但我不推薦)

@RequestMapping(value="/api/employee") 
@Controller 
public class EmployeeSvc 

     public Employee getEmployee(@PathVariable empID){ 
     ..... 
     } 

     @RequestMapping(value="{empID}/homeaddress") 
     public Address getHomeAddress(@PathVariable empID){ 
      // will serve http://localhost:8080/api/employee/11111/homeaddress 
      return this.getEmployee(empID).getHomeAddress(); 
      //make sure you are using 2nd Level cache - as you retrieve object twice   
     } 

} 
+0

好點@bhantol,爲什麼在資源中加載一個集合,如果你不需要它?使其成爲API中的一個子資源。涼。 – 2014-09-23 20:50:14