對於常見問題,抱歉,在開發一個寧靜的AngularJS應用程序時,是否還有一種仍然使用JPA延遲加載實體的方法。針對JPA延遲加載Rest/AngularJS的最佳方法
在舊的JSF日子裏,當一個支持bean訪問列表時,它們都可以工作。
我正在使用EclipseLink和Spring Data,以及澤西島的寧靜端點。
問候
我
對於常見問題,抱歉,在開發一個寧靜的AngularJS應用程序時,是否還有一種仍然使用JPA延遲加載實體的方法。針對JPA延遲加載Rest/AngularJS的最佳方法
在舊的JSF日子裏,當一個支持bean訪問列表時,它們都可以工作。
我正在使用EclipseLink和Spring Data,以及澤西島的寧靜端點。
問候
我
一般來說,你不得不觸發之前的EntityManager
實體的延遲加載請求的生命週期中被關閉。
爲此,您可以使用「在視圖中打開EntityManager」模式。 Spring提供您可以申請的Filter
:OpenEntityManagerInViewFilter
(請閱讀文檔:http://docs.spring.io/spring/docs/4.1.0.RELEASE/javadoc-api/org/springframework/orm/jpa/support/OpenEntityManagerInViewFilter.html)。
或者,您可以在將JPA實體序列化爲JSON之前手動調用getMyLazyCollection()
。
我認爲最好的課程取決於以下幾點。
您是否能夠檢索完全解析的實體,即其所有 組件,而不會對性能產生負面影響?
如果答案是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
}
}
好點@bhantol,爲什麼在資源中加載一個集合,如果你不需要它?使其成爲API中的一個子資源。涼。 – 2014-09-23 20:50:14
解決'getMyLazyCollection()'你是否表示在返回JSON之前整個實體將被解析爲服務器端? – bhantol 2014-09-22 19:28:01
實體需要在服務器端的某個點解決。因此,如果您在此期間(通過過濾器)打開了EntityManager,或者在JSON序列化之前(如果您明確調用getter方法),那麼會在JSON序列化期間發生(遍歷對象圖)。當然,您可以將實體的懶集合標記爲不可序列化(通過Jackson2),然後再通過「@ JsonIgnore」再次調用服務器以獲取集合。不知道如何適合你的確切用例。 – 2014-09-23 20:27:30