Bean injection inside a JPA @Entity

前端 未结 3 2176
抹茶落季
抹茶落季 2020-11-27 05:31

Is it possible to inject beans to a JPA @Entity using Spring\'s dependency injection?

I attempted to @Autowire ServletContext but, while the server did

3条回答
  •  夕颜
    夕颜 (楼主)
    2020-11-27 06:26

    Yes, of course you can. You just need to make sure the entity is also registered as a Spring managed bean either declaratively using tags (in some spring-context.xml) or through annotations as shown below.

    Using annotations, you can either mark your entities with @Component (or a more specific stereotype @Repository which enables automatic exception translation for DAOs and may or may not interfere with JPA).

    @Entity
    @Component
    public class MyJAPEntity {
    
      @Autowired
      @Transient
      ServletContext servletContext;
      ...
    }
    

    Once you've done that for your entities you need to configure their package (or some ancestor package) for being scanned by Spring so that the entities get picked up as beans and their dependencies get auto wired.

    
      ...
      
    
    

    EDIT : (what finally worked and why)

    • Making the ServletContext static. (remove @Autowired)

      @Transient
      private static ServletContext servletContext;
      

    Since, JPA is creating a separate entity instance i.e. not using the Spring managed bean, it's required for the context to be shared.

    • Adding a @PostConstruct init() method.

      @PostConstruct
      public void init() {
          log.info("Initializing ServletContext as [" +
                      MyJPAEntity.servletContext + "]");
      }
      

    This fires init() once the Entity has been instantiated and by referencing ServletContext inside, it forces the injection on the static property if not injected already.

    • Moving @Autowired to an instance method but setting the static field inside.

      @Autowired
      public void setServletContext(ServletContext servletContext) {
          MyJPAEntity.servletContext = servletContext;
      }
      

    Quoting my last comment below to answer why do we have to employ these shenanigans:

    There's no pretty way of doing what you want since JPA doesn't use the Spring container to instantiate its entities. Think of JPA as a separate ORM container that instantiates and manages the lifecycle of entities (completely separate from Spring) and does DI based on entity relationships only.

提交回复
热议问题