3 回答

TA貢獻1776條經驗 獲得超12個贊
您必須對延遲集合進行顯式調用才能對其進行初始化(通常的做法是.size()為此目的而調用)。在Hibernate中,有一個專用于此(Hibernate.initialize())的方法,但是JPA沒有與此等效的方法。當然,當會話仍然可用時,您必須確保調用已完成,因此請使用注釋控制器方法@Transactional。一種替代方法是在控制器和存儲庫之間創建一個中間服務層,該服務層可以公開初始化惰性集合的方法。
更新:
請注意,上述解決方案很簡單,但是會導致對數據庫進行兩個不同的查詢(一個用于用戶,另一個用于其角色)。如果要獲得更好的性能,請在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子句在一次往返數據庫中熱切地加載角色關聯,因此將減輕上述解決方案中兩個截然不同的查詢引起的性能損失。

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