当前位置: 首页 > 面试题库 >

Spring Data JPA-“无法初始化代理-没有会话”-将方法标记为事务性

国斌斌
2023-03-14
问题内容

我有一个模型,该模型具有相当大的子实体图,并且hibernate最终制作了大约9条语句来懒惰地获取所有所需的数据,但是深度约4层时,出现“无法初始化代理-
没有会话”错误,我不知道为什么。

控制者

@Transactional(readOnly = true)
@RequestMapping(value = "/v2/plans", method = RequestMethod.GET)
public @ResponseBody List<PlanPresenter> show(HttpServletRequest request) throws Exception {
  List<PlanPresenter> planPresenters = new ArrayList<>();

  CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
  CriteriaQuery<Plan> planQuery = criteriaBuilder.createQuery(Plan.class);
  Root<Plan> root = planQuery.from(Plan.class);

  if (request.getParameter("region") != null || request.getParameter("group") != null) {
    List<Predicate> criteria = new ArrayList<Predicate>();
    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<Plan>)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<String, Object> details = new HashMap<String, Object>();

  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<String> 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<Rider> 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<String, Object>> getRiders() {
    List<HashMap<String, Object>> riders = new ArrayList<HashMap<String, Object>>();
    if (this.riders != null && this.riders.size() > 0) {
      this.riders.forEach((rider) -> {
        HashMap<String, Object> planRider = new HashMap<String, Object>();
        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<BrochureSection> 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.<init>(PlanPresenter.java:20) ~[classes/:?]
at com.controllers.v2.PlansController.show(PlansController.java:64) ~[classes/:?]

任何帮助,将不胜感激。


问题答案:

如果您希望保持 延迟加载 并且正在使用Spring Boot,只需在 application.properties中 添加以下配置:

spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true


 类似资料:
  • 我有一个模型,它有一个相当大的子实体图,hibernate最终生成了大约9条语句来懒洋洋地获取所需的所有数据,但大约有4层深,我得到了一个“无法初始化代理-没有会话”错误,我不知道为什么。 控制器 节目主持人 计划 计划详情 小册子部分 例外 任何帮助都将不胜感激。

  • 问题内容: 我有一个看起来像这样的错误: 无法初始化代理-没有会话 我正在使用java,hibernate和spring。尝试生成PDF文档时会出现此错误,我正在按照以下步骤即时生成它并存储在数据库中。 我通过POST方法向应用发送了请求。这将即时生成PDF并显示给用户。 在该请求之后,我发送了另一个请求,但是通过ajax发送了一个请求。这将生成相同的PDF,但会将其保存在数据库中。 该错误表明由

  • 问题内容: 我有2台物理服务器,我的Web应用程序命中该服务器由负载均衡器管理。我总是得到- org.hibernate.LazyInitializationException:无法初始化代理-没有会话 当其中一台服务器受到攻击而另一台服务器运行平稳而没有任何问题时。我有一个由应用程序启用和管理的本地托管缓存存储。仅当尝试从一个表访问一个特定的列时,才会发生此异常。不管选择哪个服务器,其余的操作都

  • 问题内容: 我的代码检索与用户有关的所有信息: 在简单地返回一组用户的ES。 我的问题是:即使会话已经关闭,为什么对象仍然具有其值(例如名称)?是该类的实例变量。但是为什么我不能检索其值却可以检索该类的常规实例变量? 是一个。 问题答案: 有关使用惰性关联的hibernate文档清楚地将这种访问称为错误。只有在会话仍处于打开状态时,才能与延迟关联的对象进行交互。文档的该部分还提供了访问对象的延迟关

  • 问题内容: 对数据库有以下查询: 在获取employee.address.street,employee.address.houseNumber或employee.address.city时,它将失败,但以下情况除外: 员工映射: 地址映射: 对于其他类(办公室,公司等),这​​是绝对正常的。如果注释,则在jsp应用程序中加载地址字段的行将正常工作。怎么了?顺便说一下,尽管有异常,它仍显示有关js

  • 问题内容: 我试图从数据库中的对象进行简单加载,但出现错误“无法初始化代理-没有会话”,知道吗?谢谢 问题答案: 尝试添加到validate方法: 发生的事情是,因为没有注释,所以没有与该方法关联的会话,并且每个查询都将在其自己的会话中运行,该会话随后将立即关闭。 该方法始终返回一个代理,与之不同(请参阅此处,了解load与get之间的差异)。 因此,返回了代理,但是由于缺少代理,因此立即关闭了创