Spring-boot EntityListener,应用程序上下文中的一些bean的依赖关系形成一个循环

Anu*_*kar 5 java dependency-injection jpa entitylisteners spring-boot

我在以下设计中面临依赖循环(摘自此处)。

\n

我有 2 个实体 Post 和 PostLog。创建 Post 后,我​​也想将其保留在 PostLog 中。因此创建了侦听器并将其应用于“Post”实体。实体 Post 和 PostLog 也都使用 spring-boot“AuditingEntityListener”,但为了简单起见,我没有在此处添加该代码。

\n

我的实体和监听器结构 -

\n
@Data\n@EqualsAndHashCode(callSuper = false)\n@Entity\n@Table(name = "post")\n@EntityListeners({AuditingEntityListener.class, PostLogListener.class})\npublic class Post extends Auditable<String> {\n...\n}\n\n@Data\n@EqualsAndHashCode(callSuper = false)\n@Entity\n@Table(name = "post_log")\n@EntityListeners(AuditingEntityListener.class)\npublic class PostLog extends Auditable<String> {\n...\n}\n\n@Component\n@RequiredArgsConstructor\npublic class PostLogListener {\n  \n  private final PostLogRepository repo;\n\n  @PostPersist\n  @Transactional(propagation = Propagation.REQUIRES_NEW)\n  public void logEvent(final Post post) {\n    PostLog log = createLog(post); // implementation is omitted here for keeping short\n    repo.save(log);\n  }\n}\n\n@Repository\npublic interface PostLogRepository extends CrudRepository<PostLog, Long> {}\n
Run Code Online (Sandbox Code Playgroud)\n

我收到错误 -

\n
***************************\nAPPLICATION FAILED TO START\n***************************\n\nDescription:\n\nThe dependencies of some of the beans in the application context form a cycle:\n\n\xe2\x94\x8c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x90\n|  entityManagerFactory defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]\n\xe2\x86\x91     \xe2\x86\x93\n|  com.example.listener.PostLogListener\n\xe2\x86\x91     \xe2\x86\x93\n|  postLogRepository defined in com.example.repository.PostLogRepository defined in @EnableJpaRepositories declared on JpaRepositoriesRegistrar.EnableJpaRepositoriesConfiguration\n\xe2\x86\x91     \xe2\x86\x93\n|  (inner bean)#53c2dd3a\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x98\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n

San*_*wat 15

使用惰性初始化来解决循环依赖。为此,您需要自己创建构造函数来注入 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);
  }
}
Run Code Online (Sandbox Code Playgroud)

注意 - 如果任何注入的 Bean 依赖于 EntityManager,则这是必需的。Spring Data存储库依赖于EntityManager,因此任何具有存储库或直接entityManager的bean都会形成一个循环。 Spring 依赖注入到 JPA 实体监听器中