Spring Data JPA – “无法初始化代理 – 无会话” – 使用标记为事务的方法

我有一个模型有一个相当大的子实体图和hibernate最终制作大约9个语句懒洋洋地获取所需的所有数据,但约4级深我得到一个“无法初始化代理 – 没有会话”错误,我是不知道为什么。

调节器

@Transactional(readOnly = true) @RequestMapping(value = "/v2/plans", method = RequestMethod.GET) public @ResponseBody List show(HttpServletRequest request) throws Exception { List planPresenters = new ArrayList(); CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder(); CriteriaQuery planQuery = criteriaBuilder.createQuery(Plan.class); Root root = planQuery.from(Plan.class); if (request.getParameter("region") != null || request.getParameter("group") != null) { List criteria = new ArrayList(); if (request.getParameter("region") != null) { criteria.add(criteriaBuilder.equal(root.get(Plan_.region), request.getParameter("region"))); } if (request.getParameter("group") != null) { criteria.add(criteriaBuilder.equal(root.get(Plan_.groupCode), request.getParameter("group"))); criteria.add(root.get(Plan_.planSetId).in(groupPlanSetIds)); } else { criteria.add(root.get(Plan_.planSetId).in(currentPlanSetIds)); } Query query = entityManager.createQuery(planQuery.where(criteriaBuilder.and(criteria.toArray(new Predicate[]{})))); for (Plan plan : (List)query.getResultList()) { planPresenters.add(new PlanPresenter(plan)); } } return planPresenters; } 

主持人

 public class PlanPresenter { public String id; public String plan_set_id; public String region; public String name; public String description; public HashMap details = new HashMap(); public PlanPresenter(Plan plan) throws Exception { this.id = String.valueOf(plan.id); this.plan_set_id = String.valueOf(plan.planSetId); this.region = plan.region.trim(); this.name = plan.getName(); this.description = plan.getDescription(); this.details.put("spanish_plan", plan.isSpanishPlan()); this.details.put("mutually_exclusive", plan.isMutuallyExclusive()); this.details.put("group_plan", plan.isGroupPlan()); this.details.put("group_code", plan.groupCode.trim()); this.details.put("family_plan", plan.isFamilyPlan()); this.details.put("price", plan.getPrice()); this.details.put("enrollment_fee", plan.getEnrollmentFee()); this.details.put("riders", plan.getRiders()); } } 

计划

 @Entity public class Plan implements Serializable { private static final long serialVersionUID = 7639611964474770505L; private static List familyPlanShortNames = Arrays.asList("ABCD"); @Transient private String description = ""; (Column definitions) @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "XXXX", insertable = false, updatable = false, nullable = true) @NotFound(action = NotFoundAction.IGNORE) public PlanDetail planDetail; @OneToMany(fetch = FetchType.LAZY) @JoinColumn(name = "XXXX", insertable = false, updatable = false, nullable = true) @OrderBy("XXXX") @NotFound(action = NotFoundAction.IGNORE) public List riders; public String getName() { return this.planDetail != null ? this.planDetail.longName.trim() : null; } public Boolean isSpanishPlan() { return this.language.trim().equals("ES"); } public Boolean isMutuallyExclusive() { return this.mutuallyExclusive.trim().equals("Y"); } public Boolean isGroupPlan() { return this.groupCode != null && !this.groupCode.trim().equals(""); } public Boolean isFamilyPlan() { return familyPlanShortNames.contains(this.planDetail.shortName.trim()); } public BigDecimal getPrice() { return this.planDetail != null ? this.planDetail.price.setScale(2) : null; } public BigDecimal getEnrollmentFee() { return this.planDetail != null ? this.planDetail.enrollmentFee.setScale(2) : null; } public String getDescription() { if (this.planDetail != null && this.planDetail.brochureSections != null) { this.planDetail.brochureSections.forEach((brochureSection) -> { if (brochureSection.type.trim().equals("P1") && brochureSection.order == 1) { this.description = this.description + " " + brochureSection.text.trim(); } }); } return this.description.trim(); } public List<HashMap> getRiders() { List<HashMap> riders = new ArrayList<HashMap>(); if (this.riders != null && this.riders.size() > 0) { this.riders.forEach((rider) -> { HashMap planRider = new HashMap(); planRider.put("name", rider.getName()); planRider.put("price", rider.getPrice()); planRider.put("description", rider.getDescription()); riders.add(planRider); }); } return riders; } } 

计划细节

 @Entity public class PlanDetail implements Serializable { private static final long serialVersionUID = 2256881691562712018L; (Column definitions) @OneToMany(fetch = FetchType.LAZY) @JoinColumn(name = "XXXX", referencedColumnName = "XXXX", insertable = false, updatable = false, nullable = true) @OrderBy("XXXX") @NotFound(action = NotFoundAction.IGNORE) public List brochureSections; } 

宣传册部分

 @Entity public class BrochureSection implements Serializable { private static final long serialVersionUID = 1856191232387921427L; (Column definitions) } 

例外

 org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.models.PlanDetail.brochureSections, could not initialize proxy - no Session at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:576) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:215) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:555) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:143) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] at org.hibernate.collection.internal.PersistentBag.iterator(PersistentBag.java:294) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] at java.lang.Iterable.forEach(Iterable.java:74) ~[?:1.8.0_66] at com.models.Plan.getDescription(Plan.java:100) ~[classes/:?] at com.presenters.v2.PlanPresenter.(PlanPresenter.java:20) ~[classes/:?] at com.controllers.v2.PlansController.show(PlansController.java:64) ~[classes/:?] 

任何帮助,将不胜感激。

如果您想保留Lazy Load并且使用Spring Boot,只需在application.properties中添加以下配置:

 spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true