2 metody pobierajace listę, a tylko jedna zwraca LazyInitializationException

0

Mam taki problem.
W serwisie posiadam 2 metody, ktorych wynikiem działania jest zwrócenie listy. Każda z nich po tym co ma zrobić, pobiera liste w dokładnie ten sam sposób

    @Override
    public List<RelationEntity> addRelation(RelationEntity relationEntity)
            throws TooManyNullFieldsException, AscendanceViolationException, IncorrectStatusException, NotExistingMemberException, NotExistingRelationException {
        FamilyEntity familyEntity = familyService.findFamilyById(relationEntity.getFamily().getId());

        /*
           Validate relation
         */
        relationValidator.validate(relationEntity, familyEntity);

        relationEntity = setMembersToCorrectPlace(relationEntity);

        /*
         * Verify Existing
         */
        RelationEntity existing = relationService.findRelationBySimLeftAndSimRight
                (relationEntity.getLeft(),
                relationEntity.getRight());
        /*
            Prepare target
         */
        RelationEntity target = existing == null ?
                relationService.addNewRelation(relationEntity) : mergeChildrenAndStatus(existing, relationEntity);
        
        
        return relationService.findAllRelationsByFamilyId(target.getFamily().getId());
    }

    @Override
    public List<RelationEntity> updateRelation(RelationEntity relationEntity) throws NotExistingRelationException {
        RelationEntity existing = relationService.findRelationById(relationEntity.getId());
        existing.setActive(relationEntity.isActive());
        existing.setType(relationEntity.getType());

        existing = relationService.updateRelation(target);
        List<RelationEntity> targetList = relationService.findAllRelationsByFamilyId(existing.getFamily().getId());

        Hibernate.initialize(targetList);
        targetList.forEach(Hibernate::initialize);
        return targetList;
    }

Metoda AddRelation działa prawidłowo, natomiast updateRelation zwraca LazyInitializationException w momencie konwersji entityDoDTO. Na wyjsciu obydwu metod dokonywana jest konwersja dokladnie w taki sam sposób.
Jak widac wyżej, próbowałam to ratowac używając Hibernate.initialize ale nie działa. Ma ktos jakiś pomysł dlaczego podobne wywołanie działa w jednym przypadku a w innym nie ?

0

Pytanie zasadnicze to gdzie jest startowana i zamykana sesja hibernate. (Transaction). Jaka to technologia (framework?)?
I ewntualnie na której dokładnie operacji w konwersji na DTO leci exception.

Z drobnych uwag- nie to stanowi problem, ale: na pewno ma sens deklarować tyle throws przy pierwszej metodzie ? faktycznie te wyjątki są na zupełnie różny sposób obsługiwane?

0
jarekr000000 napisał(a):

Pytanie zasadnicze to gdzie jest startowana i zamykana sesja hibernate. (Transaction). Jaka to technologia (framework?)?
I ewntualnie na której dokładnie operacji w konwersji na DTO leci exception.

Z drobnych uwag- nie to stanowi problem, ale: na pewno ma sens deklarować tyle throws przy pierwszej metodzie ? faktycznie te wyjątki są na zupełnie różny sposób obsługiwane?

W zasadzie to bede chciala je zgrupowac.. ale chwilowo niech będzie tak.

Jeżeli chodzi o tranzakcyjnaosc to @Trasanction jest ustaawione na Servisie w którym zadeklarowane sa te metody . Ten serwis uderza w inne mniejsze serwisy ( jak widac na listeningu), który juz nie jest transakcyjny. Nastepnie fasada zajmuje sie konwersja. Czyli wyglada to tak

https://imgur.com/gbSpt2x

Ale dalej zastanaiwa mnie, skoro uzywam tych samych metod to czemu raz prawidlowo sa pobrane elementy a raz nie.

0

Albo sprawdź na czym dokładnie się wywala lazyinitialization i to dokładnie pole inicializuj.... obecne Hibernate.initialize jest bez sensu użyte.
albo może nawet lepiej - zrób konwersję do DTO już w tych metodach.

0
jarekr000000 napisał(a):

Albo sprawdź na czym dokładnie się wywala lazyinitialization i to dokładnie pole inicializuj.... obecne Hibernate.initialize jest bez sensu użyte.
albo może nawet lepiej - zrób konwersję do DTO już w tych metodach.

Po to mam fasade aby ona robila konwersje na DTO.. poza tym nadal nie uzyskalam odpowiedzi, dlaczego, uzywajac tej samej metody na wyciagniecie listy z bazy w 2 funkcjach tylko jedna z nich wywala error.

0
  1. Metody nie są takie same.
  2. Problem jest własnie w fasadzie, która wyciąga dane z tych obiektów i wkłada do DTO. (No bo przecież tam leci błąd!).
    Albo dojdziesz, które dokładnie pole nie jest zainicjalizowane, albo dorzucisz @Transactional do fasady.
0
jarekr000000 napisał(a):
  1. Metody nie są takie same.
  2. Problem jest własnie w fasadzie, która wyciąga dane z tych obiektów i wkłada do DTO. (No bo przecież tam leci błąd!).
    Albo dojdziesz, które dokładnie pole nie jest zainicjalizowane, albo dorzucisz @Transactional do fasady.

Chodziło mi o to że w obydwu metodach na samym koncu wywolywane i zwracane jako wynik jest to :

relationService.findAllRelationsByFamilyId(target.getFamily().getId());

I w zasadzie nic z tym nie jest robione poza tym ze jest to zwracane. ( nota bene w tej metodzie gdzie zaczelama dodawac initialize, wywala sie blad. Ale ten initialize jest tam w wyniku prób rozwiązania problemu). Fasada dla obydwu metod tez niewiele się rozni..

@Override
 public List<RelationDTO> addRelation(RelationDTO relation) throws TooManyNullFieldsException, AscendanceViolationException, IncorrectStatusException, NotExistingMemberException, NotExistingRelationException {
     RelationEntity relationEntity = converterToEntity.convert(relation);
     List<RelationEntity> list = projectService.addRelation(relationEntity);
     List<RelationDTO> target = converterToDTO.convertFullRelationList(list);
     return target;
 }

 @Override
 public List<RelationDTO> updateRelation(RelationDTO relation) throws NotExistingRelationException {
     RelationEntity relationEntity = converterToEntity.convert(relation);
     List<RelationEntity> list = projectService.updateRelation(relationEntity);
     List<RelationDTO> target = converterToDTO.convertFullRelationList(list);
     return target;
 }

Dlatego ja nie widze najmniejszego powodu dla ktorego to akurat w updateRelation wywala sie blad a AddRelation przechodzi ok.

0

Jakbyć podała na której dokładnie operacji w convertFullRelationList się wywala to byłoby troche łatwiej.
To, że dwie metody zwracają ten sam typ - to nie znaczy, że są tam te same dane - a tu wali się, bo pewnie metoda updateRelation nie incjalizjuje pól "children". A metoda addRelation robi to przypadkiem (
w mergeChildrenAndStatus(existing, relationEntity);.

Z tego wynikałoby, że powinnaś coś takiego dodać:
targetList.forEach(r -> Hibernate.initialize(r.getChildren()); (nie wiem jak to pole się nazywa naprawdę)

0
jarekr000000 napisał(a):

Jakbyć podała na której dokładnie operacji w convertFullRelationList się wywala to byłoby troche łatwiej.
To, że dwie metody zwracają ten sam typ - to nie znaczy, że są tam te same dane - a tu wali się, bo pewnie metoda updateRelation nie incjalizjuje pól "children". A metoda addRelation robi to przypadkiem (
w mergeChildrenAndStatus(existing, relationEntity);.

Z tego wynikałoby, że powinnaś coś takiego dodać:
targetList.forEach(r -> Hibernate.initialize(r.getChildren()); (nie wiem jak to pole się nazywa naprawdę)

To ma nawet sens, bo tak ostatecznie zrobilam. Ale... jak widzisz mergeChildrenAndStatus, jest wykonywane dla 2 konkretnych egzemplarzy relationEntity tylko.. W moich testach jak dodawalam relacje to robilam to bez dzieci, wiec ta metoda nic nie robila. Poza tym to co jest zwracane, to jest w osobnym zapytaniu do bazy.

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