简体   繁体   English

Micronaut 数据问题懒惰地获取相关实体

[英]Micronaut data problem lazily fetching related entities

I am currently in the process of incorporating micronaut data into an existing micronaut project (as part of upgrading it) and I am experiencing some problems regarding lazily fetching related collections (with a OneToMany relation).我目前正在将 micronaut 数据合并到现有的 micronaut 项目中(作为升级的一部分),并且在延迟获取相关的 collections(具有OneToMany关系)方面遇到了一些问题。

I have the following entity structure:我有以下实体结构:

@Data
@Entity
@NoArgsConstructor
@AllArgsConstructor
@Builder(toBuilder = true)
public class Merchant implements Serializable {

  @Id private String name;

  private String displayName;

  private String staticSiteAddress;

  private String emailFromAddress;

  private String emailFromName;

  private String etmEmailFromAddress;

  private String etmEmailFromName;

  private String phone;

  private String username;

  @Embedded private PasswordHash password;

  @ToString.Exclude
  @EqualsAndHashCode.Exclude
  @OneToMany(mappedBy = "merchant", fetch = FetchType.LAZY)
  @Builder.Default
  private Set<MerchantStore> stores = new HashSet<>();

  @ToString.Exclude
  @EqualsAndHashCode.Exclude
  @OneToMany(mappedBy = "merchant", fetch = FetchType.LAZY)
  @Builder.Default
  private Set<CustomWebLink> customWebLinks = new HashSet<>();

  @ToString.Exclude
  @EqualsAndHashCode.Exclude
  @OneToMany(mappedBy = "merchant", fetch = FetchType.LAZY)
  @Builder.Default
  private Set<LoyaltyPlan> loyaltyPlans = new HashSet<>();

  @ToString.Exclude
  @EqualsAndHashCode.Exclude
  @OneToMany(mappedBy = "merchant", fetch = FetchType.LAZY)
  @Builder.Default
  private Set<MerchantPref> merchantPrefs = new HashSet<>();

}

With in on hand I am able to fetch the first level related entities fine (ie merchantPrefs ) with no issue using the following repository method:在手头上,我可以使用以下存储库方法毫无问题地获取第一级相关实体(即merchantPrefs ):

@NonNull
@Override
@Cacheable("merchant")
@Join(value = "stores", type = Join.Type.LEFT_FETCH)
@Join(value = "customWebLinks", type = Join.Type.LEFT_FETCH)
@Join(value = "merchantPrefs", type = Join.Type.LEFT_FETCH)
@Join(value = "loyaltyPlans", type = Join.Type.LEFT_FETCH)
Optional<Merchant> findById(@NonNull @NotNull String s);

However when I try to fetch an innermost collection for example awards from this entity:但是,当我尝试从该实体获取最里面的集合(例如awards )时:

@Data
@Entity
public class LoyaltyPlan implements Serializable {

  @EmbeddedId private LoyaltyPlanID id;

  @ToString.Exclude
  @EqualsAndHashCode.Exclude
  @ManyToOne(fetch = FetchType.LAZY)
  @MapsId("merchant")
  @JoinColumn(name = "merchant", nullable = false)
  private Merchant merchant;

  private String displayName;

  private String emailFromName;

  private String emailFromAddress;

  private String uniqueId;

  private boolean defaultPlan;

  private float pointsFactor;

  private boolean hasGiftCards;

  private boolean hasLoyaltyCards;

  private boolean usesName;

  private boolean hasEmail;

  private boolean hasCellPhone;

  private boolean needsGiftCards;

  private boolean needsLoyaltyCards;

  private boolean needsName;

  private boolean needsEmail;

  private boolean needsCellPhone;

  private int signupBonus;

  private int closingAwardThreshold;

  private int maxPointsPerOrder;

  private int minPricePerOrder;

  private int recentHistoryDays;

  private int expiringCouponReminderDays;

  @ToString.Exclude
  @EqualsAndHashCode.Exclude
  @OneToMany(mappedBy = "loyaltyPlan", fetch = FetchType.LAZY)
  private List<LoyaltyPlanAward> awards;
}

I get a LazyInitializationException .我得到一个LazyInitializationException

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: fts.marketing.entities.plan.LoyaltyPlan.awards, could not initialize proxy - no Session
    at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:606)
    at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:218)
    at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:585)
    at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:149)
    at org.hibernate.collection.internal.PersistentBag.iterator(PersistentBag.java:387)
    at java.base/java.lang.Iterable.forEach(Iterable.java:74)
    at fts.marketing.TestController.doSomething(TestController.java:29)
    at fts.marketing.$TestControllerDefinition$Intercepted.$$access$$doSomething(Unknown Source)
    at fts.marketing.$TestControllerDefinition$$exec1.invokeInternal(Unknown Source)
    at io.micronaut.context.AbstractExecutableMethod.invoke(AbstractExecutableMethod.java:146)
    at io.micronaut.aop.chain.MethodInterceptorChain.proceed(MethodInterceptorChain.java:73)
    at io.micronaut.transaction.interceptor.TransactionalInterceptor.intercept(TransactionalInterceptor.java:134)
    at io.micronaut.aop.chain.MethodInterceptorChain.proceed(MethodInterceptorChain.java:82)
    at fts.marketing.$TestControllerDefinition$Intercepted.doSomething(Unknown Source)
    at fts.marketing.$TestControllerDefinition$$exec1.invokeInternal(Unknown Source)
    at io.micronaut.context.AbstractExecutableMethod.invoke(AbstractExecutableMethod.java:146)
    at io.micronaut.context.DefaultBeanContext$4.invoke(DefaultBeanContext.java:474)
    at io.micronaut.web.router.AbstractRouteMatch.execute(AbstractRouteMatch.java:312)
    at io.micronaut.web.router.RouteMatch.execute(RouteMatch.java:118)
    at io.micronaut.http.server.netty.RoutingInBoundHandler.lambda$buildResultEmitter$10(RoutingInBoundHandler.java:1369)
    at io.reactivex.internal.operators.flowable.FlowableDefer.subscribeActual(FlowableDefer.java:35)
    at io.reactivex.Flowable.subscribe(Flowable.java:14935)
    at io.reactivex.Flowable.subscribe(Flowable.java:14882)
    at io.micronaut.http.server.context.ServerRequestContextFilter.lambda$doFilter$0(ServerRequestContextFilter.java:62)
    at io.reactivex.internal.operators.flowable.FlowableFromPublisher.subscribeActual(FlowableFromPublisher.java:29)
    at io.reactivex.Flowable.subscribe(Flowable.java:14935)
    at io.reactivex.Flowable.subscribe(Flowable.java:14885)
    at io.micronaut.http.server.netty.RoutingInBoundHandler.lambda$buildExecutableRoute$6(RoutingInBoundHandler.java:1074)
    at io.micronaut.web.router.DefaultUriRouteMatch$1.execute(DefaultUriRouteMatch.java:80)
    at io.micronaut.web.router.RouteMatch.execute(RouteMatch.java:118)
    at io.micronaut.http.server.netty.RoutingInBoundHandler.handleRouteMatch(RoutingInBoundHandler.java:698)
    at io.micronaut.http.server.netty.RoutingInBoundHandler.channelRead0(RoutingInBoundHandler.java:554)
    at io.micronaut.http.server.netty.RoutingInBoundHandler.channelRead0(RoutingInBoundHandler.java:1

Furthemore this seems to be a sporadic issue, as sometimes the same code seems to be working OK.此外,这似乎是一个零星的问题,因为有时相同的代码似乎工作正常。 I am not really sure what is wrong and I think I have modelled the relations correctly as those have been fine before migrating to micronaut-data .我不太确定出了什么问题,我认为我已经正确地对关系进行了建模,因为在迁移到micronaut-data之前这些关系都很好。

I do not know what I am doing wrong here and any help would highly appreciated in order to resolve this.我不知道我在这里做错了什么,为了解决这个问题,我们将不胜感激任何帮助。

In Micronaut the concept of OpenSessionInView doesn't exist.在 Micronaut 中,不存在OpenSessionInView的概念。 It seems that you are trying to access to the relation when the transaction is already closed.当事务已经关闭时,您似乎正在尝试访问该关系。 Look at this: https://micronaut-projects.github.io/micronaut-sql/latest/guide/index.html#_understanding_lazyinitializationexception看这个: https://micronaut-projects.github.io/micronaut-sql/latest/guide/index.html#_understanding_lazyinitializationexception

Solutions:解决方案:

  1. Don't use Lazy.不要使用懒惰。 Instead go to the DB with a repository every time you need the list.而是在每次需要列表时将 go 放到带有存储库的数据库中。
  2. Use EAGER.使用渴望。
  3. Use @Transactional in the method that make the query.在进行查询的方法中使用@Transactional。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM