簡體   English   中英

Spring-boot EntityListener,應用上下文中一些bean的依賴形成一個循環

[英]Spring-boot EntityListener, The dependencies of some of the beans in the application context form a cycle

我在以下設計中面臨依賴循環(取自此處)。

我有 2 個實體 Post 和 PostLog。 創建 Post 后,我也想將其保留在 PostLog 中。 因此創建了偵聽器並將其應用於“發布”實體。 實體 Post 和 PostLog 也使用 spring-boot “AuditingEntityListener”,但為簡單起見,我不在這里添加該代碼。

我的實體和監聽器結構 -

@Data
@EqualsAndHashCode(callSuper = false)
@Entity
@Table(name = "post")
@EntityListeners({AuditingEntityListener.class, PostLogListener.class})
public class Post extends Auditable<String> {
...
}

@Data
@EqualsAndHashCode(callSuper = false)
@Entity
@Table(name = "post_log")
@EntityListeners(AuditingEntityListener.class)
public class PostLog extends Auditable<String> {
...
}

@Component
@RequiredArgsConstructor
public class PostLogListener {
  
  private final PostLogRepository repo;

  @PostPersist
  @Transactional(propagation = Propagation.REQUIRES_NEW)
  public void logEvent(final Post post) {
    PostLog log = createLog(post); // implementation is omitted here for keeping short
    repo.save(log);
  }
}

@Repository
public interface PostLogRepository extends CrudRepository<PostLog, Long> {}

我得到的錯誤 -

***************************
APPLICATION FAILED TO START
***************************

Description:

The dependencies of some of the beans in the application context form a cycle:

┌─────┐
|  entityManagerFactory defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]
↑     ↓
|  com.example.listener.PostLogListener
↑     ↓
|  postLogRepository defined in com.example.repository.PostLogRepository defined in @EnableJpaRepositories declared on JpaRepositoriesRegistrar.EnableJpaRepositoriesConfiguration
↑     ↓
|  (inner bean)#53c2dd3a
└─────┘

我做了一些研究,但找不到正確的解決方案。

使用惰性初始化來解決循環依賴。 為此,您需要自己創建構造函數來注入 spring bean 並使用 @Lazy (org.springframework.context.annotation.Lazy)

@Component
public class PostLogListener {
  
  private final PostLogRepository repo;

  public PostLogListener(@Lazy PostLogRepository repo) {
    this.repo = repo;
  }

  @PostPersist
  @Transactional(propagation = Propagation.REQUIRES_NEW)
  public void logEvent(final Post post) {
    PostLog log = createLog(post); // implementation is omitted here for keeping short
    repo.save(log);
  }
}

注意 - 如果任何注入的 bean 依賴於 EntityManager,則這是必需的。 Spring 數據存儲庫依賴於EntityManager,因此任何具有存儲庫或直接entityManager 的bean 都會形成一個圓圈。 Spring 依賴注入到 JPA 實體監聽器

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM