복붙노트

[SPRING] Class @Entity에서 작동하지 않는 Autowired

SPRING

Class @Entity에서 작동하지 않는 Autowired

Menu라는 클래스가 있는데, @Entity로 주석을 달았습니다. GestoreMessaggi라는 클래스 내부에서 메소드를 사용해야합니다.

....    
@Component
@Entity
@Table(name="menu")
public class Menu implements Serializable{

@Autowired
@Transient // because i dont' save this field on the DB
private GestoreMessaggi gestoreMessaggi;
.....
public void setCurrentLanguage(){

   /* I got the error both if use gestoreMessaggi
   this way and if I use the autowired istance of GestoreMessaggi*/
   GestoreMessaggi gestoreMessaggi = new GestoreMessaggi();  
   gestoreMessaggi.gest();        
}
.....

이것은 GestoreMessaggi 클래스의 관련 코드입니다.

 @Component
    public class GestoreMessaggi {    
        @Autowired 
        private ReloadableResourceBundleMessageSource messageSource;

        public void gest(){
        messageSource.doSomething() <--- here messageSource is null
        }
  }

언제, 나는 gestoreMessaggi.gest ()를 호출한다. MessageSource가 null이기 때문에 Menu 클래스에서 오류가 발생했습니다. gestoreMessaggi istance가 null이 아니고 null입니다. messageSource

중요 : @Entity로 주석 된 클래스에서 GestoreMessaggi를 호출 할 때만 messageSource에 null이 발생합니다.

ds-servlet.xml에서 나는 Menu와 GestoreMessaggi 클래스를 포함하는 패키지를 검사하도록 Spring에 지시했다.

//Menu package 
<context:component-scan base-package="com.springgestioneerrori.model"/>
//Gestore messaggi package
<context:component-scan base-package="com.springgestioneerrori.internazionalizzazione"/>   

고맙습니다

해결법

  1. ==============================

    1.두 가지 접근법을 따를 수 있습니다.

    두 가지 접근법을 따를 수 있습니다.

    옵션 1로 가면 Spring의 컨텍스트에 명시 적으로 액세스하여 필요한 bean의 인스턴스를 검색해야한다.

    @Component
    public class Spring implements ApplicationContextAware {
    
        private static final String ERR_MSG = "Spring utility class not initialized";
    
        private static ApplicationContext context;
    
        @Override
        public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
            context = applicationContext;   
        }
    
        public static <T> T bean(Class<T> clazz) {
            if (context == null) {
                throw new IllegalStateException(ERR_MSG);
            }
            return context.getBean(clazz);
        }
    
        public static <T> T bean(String name) {
            if (context == null) {
                throw new IllegalStateException(ERR_MSG);
            }
            return (T) context.getBean(name);
        }
    }
    

    이 작업을 수행하려면 Spring이이 클래스를 검사하도록해야합니다.

    그런 다음 @EntityClass 내부에서 다음을 수행하십시오.

    public void setCurrentLanguage(){
        GestoreMessaggi gestoreMessaggi = Spring.bean(GestoreMessaggi.class);
        gestoreMessaggi.gest();        
    }
    

    그리고 그것은 모두가 될 것입니다. 더 이상 @Entity에 GestoreMessaggi를 autowire 할 필요는 없습니다. 또한이 접근법은 Spring이나 귀하의 도메인 클래스 (@Entity 클래스)를 Spring 클래스와 연결하기 때문에 Spring이나 커뮤니티의 어느 누구도 권장하지 않습니다.

    옵션 2로 가면, 당신이해야 할 일은 평소와 같이 autowiring을 해결하도록하지만 엔터티 (즉, DAO 또는 서비스) 외부에서, 그리고 당신의 엔터티가 당신에게 어떤 메시지 또는 어떤 것을 써야 하는지를 알려주는 것입니다 , 그냥 그것에 setter를 호출합니다. (그런 다음 요구 사항에 따라 @Entitys 속성을 @Transient로 설정할지 여부를 결정해야합니다.)

  2. ==============================

    2.Spring 컨텍스트는 엔티티를 관리하지 않습니다 (일반적으로 new를 사용하여 인스턴스화 된 객체를 관리하지 않습니다). 따라서 엔티티에서 Bean을 자동 작성 (Spring 컨텍스트에서 온) 할 수 없습니다.

    Spring 컨텍스트는 엔티티를 관리하지 않습니다 (일반적으로 new를 사용하여 인스턴스화 된 객체를 관리하지 않습니다). 따라서 엔티티에서 Bean을 자동 작성 (Spring 컨텍스트에서 온) 할 수 없습니다.

    모범 사례에서는 비즈니스 로직을 서비스 계층에 남겨두고 엔터티에만 getter 및 setter를 유지하는 것이 좋습니다.

    일반적인 접근 방법은 Service <-> DAO <-> Entity입니다. 예:

    서비스 계층 :

    @Service
    public interface GestoreMessaggi {
        public void gest();
    }
    
    public class GestoreMessaggiImpl implements GestoreMessaggi {
    
        @Autowired
        private MenuDao menuDao;
    
        @Override
        public void gest() {
            // 1) retrieve your entity instance with menuDao
            // 2) do stuffs with your entity
            // 3) maybe save your entity using menuDao
        }
    }
    

    DAO 계층 :

    Spring Data Jpa를 사용하는 경우 :

    public interface MenuDao extends JpaRepository<Menu, [menu-id-type]> {}
    

    그밖에:

    public interface MenuDao {
        public Menu findOne([menu-id-type] id);
        public Menu save(Menu menu);
        // other methods for accessing your data
    }
    
    @Repository
    public class MenuDaoImpl {
        // inject EntityManager or Hibernate SessionFactory
        // implement your DAO interface accessing your entities
    }
    

    마지막으로 @Services와 @Repository를 포함하여 Spring의 bean을 설정 (명시 적 또는 패키지 스캐닝)으로 설정하는 것을 잊지 마십시오.

    Spring MVC를 사용하면 컨트롤러는 @Controller 클래스에 @Services를 삽입 (autowire)해야하므로 컨트롤러는 데이터에 액세스하는 DAO 메서드를 호출하는 서비스 메서드를 호출 할 수 있습니다.

  3. from https://stackoverflow.com/questions/28365154/autowired-not-working-in-a-class-entity by cc-by-sa and MIT license