3 回答

TA貢獻(xiàn)1776條經(jīng)驗 獲得超12個贊
您必須對延遲集合進(jìn)行顯式調(diào)用才能對其進(jìn)行初始化(通常的做法是.size()為此目的而調(diào)用)。在Hibernate中,有一個專用于此(Hibernate.initialize())的方法,但是JPA沒有與此等效的方法。當(dāng)然,當(dāng)會話仍然可用時,您必須確保調(diào)用已完成,因此請使用注釋控制器方法@Transactional。一種替代方法是在控制器和存儲庫之間創(chuàng)建一個中間服務(wù)層,該服務(wù)層可以公開初始化惰性集合的方法。
更新:
請注意,上述解決方案很簡單,但是會導(dǎo)致對數(shù)據(jù)庫進(jìn)行兩個不同的查詢(一個用于用戶,另一個用于其角色)。如果要獲得更好的性能,請在Spring Data JPA存儲庫接口中添加以下方法:
public interface PersonRepository extends JpaRepository<Person, Long> {
@Query("SELECT p FROM Person p JOIN FETCH p.roles WHERE p.id = (:id)")
public Person findByIdAndFetchRolesEagerly(@Param("id") Long id);
}
此方法將使用JPQL的fetch join子句在一次往返數(shù)據(jù)庫中熱切地加載角色關(guān)聯(lián),因此將減輕上述解決方案中兩個截然不同的查詢引起的性能損失。

TA貢獻(xiàn)1828條經(jīng)驗 獲得超6個贊
盡管這是一篇老文章,但請考慮使用@NamedEntityGraph(Javax Persistence)和@EntityGraph(Spring Data JPA)。組合有效。
例
@Entity
@Table(name = "Employee", schema = "dbo", catalog = "ARCHO")
@NamedEntityGraph(name = "employeeAuthorities",
attributeNodes = @NamedAttributeNode("employeeGroups"))
public class EmployeeEntity implements Serializable, UserDetails {
// your props
}
然后如下所示的春季回購
@RepositoryRestResource(collectionResourceRel = "Employee", path = "Employee")
public interface IEmployeeRepository extends PagingAndSortingRepository<EmployeeEntity, String> {
@EntityGraph(value = "employeeAuthorities", type = EntityGraphType.LOAD)
EmployeeEntity getByUsername(String userName);
}

TA貢獻(xiàn)1811條經(jīng)驗 獲得超4個贊
你有一些選擇
根據(jù)RJ建議,在存儲庫上編寫一個返回初始化實體的方法。
更多工作,最佳性能。
使用OpenEntityManagerInViewFilter可使整個請求的會話保持打開狀態(tài)。
工作量少,通常在網(wǎng)絡(luò)環(huán)境中可以接受。
需要時,使用幫助器類來初始化實體。
較少的工作,在未選擇OEMIV時(例如在Swing應(yīng)用程序中)很有用,但在存儲庫實現(xiàn)中一次也可以初始化任何實體可能也有用。
對于最后一個選項,我編寫了一個實用程序類JpaUtils來在某些時候初始化實體。
例如:
@Transactional
public class RepositoryHelper {
@PersistenceContext
private EntityManager em;
public void intialize(Object entity, int depth) {
JpaUtils.initialize(em, entity, depth);
}
}
添加回答
舉報