sessionFactory == null

0

Witam,
Mam TaskDAOHibernate:

@Component
public class TaskDAOHibernate implements TaskDAO {
    private SessionFactory sessionFactory;

    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }
...
 

W kontrolerach mam np:

private ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
    private TaskDAO taskDAO = context.getBean(TaskDAO.class);

i wszystko dziala dobrze.
Nie chcialem tworzyc nowego kontekstu z kazdym kontrolerem, wiec wymyslilem, ze zrobie @Autowired dla beanow:

public class Server {

    //@Autowired
    TaskDAO taskDAO;

W spring.xml:

 <bean id="taskDAO" class="... .TaskDAOHibernate">
        <property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory"/>
    </bean>

Spring ladnie wstrzykuje taskDAO, ale nie ustawia tam sessionFactory (jest null) i klasa Server nie moze korzystac z DAO. Co ciekawe, pozostale klasy korzystajace z DAO (te w ktorych tworze context i biore bean sam) dzialaja dobrze.

Co robie nie tak?

0

Dopiero teraz zobaczylem co wyslalem: Oczywiscie @Autowired nie jest wykomentowane.

0

Jeśli klasa Server nie jest beanem, to nie możesz w nim używać @Autowired bo wtedy jego cykl życia nie jest obsługiwany przez Springa.

0

Zrobilem Server.class beanem:
W spring.xml:

 
<bean id="server" class="...server.Server">

    </bean>

Caly Server.class:


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
@EnableScheduling
public class Server {

    @Autowired
    TaskDAO taskDAO;

    @Scheduled(fixedRate = 1000)
    public void tick() {
        if(taskDAO == null) {
            System.out.println("taskDAO == null");
            return;
        }
        Task running = taskDAO.getFirstRunning();
    }
}

Dalej jest to samo. taskDAO wstrzykniety ale inny niz w kontrolerach i ten nie ma ustawiony sessionFactory

0

@Black007 To samo.

0

No jak tworzysz kontekst 100 razy to będziesz miał po 100 instancji tych wszystkich serwisów i sie nie dziw że inny niz w kontrolerach ;] Masz mieć JEDEN kontekst i instancjonować go tylko raz.

0

@Shalom Rozumiem. Ciagle nie rozumiem, ze gdy biore beana przez context to ma wypelnione sessionFactory, gdy biore przez @Autowired to jest null.

1

My tez nie rozumiemy. Ja głównie nie rozumiem czemu po prostu po ludzku nie podasz linka do repozytorium z tym kodem a nie liczysz że będziemy ci wróżyć z fusów...
Na oko po prostu tworzysz różne konteksty i któryś z nich w ogóle nie "zawiera" jakiegoś beana, albo wstrzykujesz przez "klasę" a nie interfejs a używasz starszej wersji Springa i nie działa bo spring nie może zrobić poprawnie dynamicznego proxy dla twojego beana. Powodów może być setka, a ja właśnie dopiłem herbatę i nie mam fusów, a szklana kula sie stłukła...

0

Prosze, o to fusy:
https://github.com/alphatica/genotick.com
Uwaga! To moj pierwszy projekt w Spring/Hibernate.

0

Że tak to ujme: WTF? o_O
To: https://github.com/alphatica/genotick.com/blob/cloud/src/main/resources/spring.xml powinieneś mieć w kontekście ładowanym przez kontener przy starcie spring mvc. A ty robisz tu jakieś cuda na kiju i 15 różnych plików z kontekstami w tym jeden ładowany zupełnie ręcznie "na pałe". Poza tym wywal te "zwykłe" beany z tego konktestu i zrób z nich @Named czy tam @Service po prostu a w kontekście daj component scan na te twoje pakiety.

Zaoraj to co tu uczyniłeś, sklonuj sobie https://github.com/Pharisaeus/SpringScaffoldApplication i wyjdź od tego. To nie jest całkiem idealne rozwiązanie bo mam jeden plik kontekstu dla mvc dispatchera i dla application context, ale można tak zrobić i dla małej aplikacji nie widzę sensu się bawić w milion plików.

0

@Shalom: dziekuje za pomoc, ale o zaoraniu nie ma mowy. na razie chce miec dzialajaca funkcjonalnosc do konca, a potem przyjdzie czas na poprawki. Jest jakis powod czemu sessionFactory jest null gdy jest @Autowired?
Dzieki

0

Powód jest taki że NIE ROZUMIESZ CO ROBISZ. Ładujesz KILKA NIEZALEŻNYCH kontekstów. One nie dzielą między sobą beanów bo są zarządzane przez zupełnie osobne kontenery.
Te twoje klasy z @Component są instancjonowane przez kontener zarządzający MVC i one są wstrzykiwane tam gdzie jest autowire z kontrolerów ale to są ZUPEŁNIE INNE OBIEKTY niż te tworzone z tego twojego spring.xml który sobie odpalasz ręcznie. Więc z ich perspektywy w ogóle nie ma tam żadnego wstrzykiwania bo przeciez twoje session factory nie ma @Autowire. I mieć nie może bo oczywiście session factory nie jest widoczne w kontenerze który je tworzy, więc autowire sprawi że aplikacja w ogóle nie wstanie.

Zaorać, spalić i napisać od nowa, tym razem polecam nie kopiować bezmyślnie kodu z tutoriali...

Albo przenieść ten kod ze spring.xml do dispatcher-servlet.xml, wywalić te wszystkie idiotyczne kody z tworzeniem kontekstu ręcznie, wszędzie dać @Inject i @Named i nie tworzyć beanów w kontekście (oprócz tego session factory i data source).

0

No dobrze. Jak zrobic aby sessionFactory bylo widoczne w kontrolerze?

0

Tak jak powiedzałem. Wywal ten plik spring.xml i te twoje cuda z tworzniem ręcznie kontekstu. Wpakuj sobie definicje session factory do kontekstu dispatcher-servlet.xml i tam tez daj component scan na wszystkie twoje paczki. Następnie wszędzie gdzie ci trzeba beanów zrób @Service albo @Named oraz @Autowire czy tam @Inject. I voila.

0

Tak lepiej? Nawet @Autowired zaczelo dzialac. Co jeszcze poprawic?

0

Czy ty w ogóle czytasz moje posty czy masz problemy z czytaniem?

  1. Jak jest component scan to spring sobie beany ZNAJDZIE. Nie musisz ich podawać w XMLu... A ty i tak pchasz tam te swoje DAO i serwisy, cholera wie po co. Ty pewnie nie wiesz po co, bo wątpie żebyś za dużo z tego kodu rozumiał. Daj tym klasom jakieś @Component czy @Named i autowire na tym session factory a nie kombinuj.
  2. Wszystko w jednym pakiecie, doskonały design, na pewno wszystko łatwo znaleźć.
  3. Ręczne otwieranie i zamykanie transakcji bo @Transactional to zbyt skomplikowana anotacja.
  4. Na kod wole nie patrzeć bo zerknąłem i widze że #rakcontent wiec wole się nie zagłębiać.
0

Wczesniej @Transactional nie chcialo dzialac. na razie poprawilem 1 i 2.
Dzieki

0

No bo robisz konfiguracje metodą Monte-Carlo to sie nie dziw że coś nie działa. Jakbyś zaczął od sklonowania projektu który podlinkowałem wyżej to nie miałbyś tylu problemów ;]

1 użytkowników online, w tym zalogowanych: 0, gości: 1