简体   繁体   中英

Apache Isis Action to list entities is too slow, found 2 issues/questions on it

Use demo app PetClinic as an example. Only focus on PetOwner, no other entities. Some pet owners are pre-inserted to the db. The action "listAll" in the demo:

    @Action(semantics = SemanticsOf.SAFE)
    @ActionLayout(bookmarking = BookmarkPolicy.AS_ROOT)
    public List<PetOwner> listAll() {
        return petOwnerRepository.findAll();
    }

When action "listAll" is called, we find two issues/questions related to the delay.

  1. Lots of queries are going out, one for each entity this is the query goes to jpa that makes sense
[EL Fine]: sql: 2022-03-10 14:50:50.303--ClientSession(1477740542)--Connection(716488272)--SELECT id, NAME, NOTES, version FROM pets.PETOWNER

and there are more queries coming:

[EL Fine]: sql: 2022-03-10 14:50:50.436--ClientSession(840311416)--Connection(1724151743)--SELECT id, NAME, NOTES, version FROM pets.PETOWNER WHERE (id = ?)
    bind => [1]
[EL Fine]: sql: 2022-03-10 14:50:50.437--ClientSession(840311416)--Connection(1724151743)--SELECT id, NAME, NOTES, version FROM pets.PETOWNER WHERE (id = ?)
    bind => [2]
[EL Fine]: sql: 2022-03-10 14:50:50.437--ClientSession(840311416)--Connection(1724151743)--SELECT id, NAME, NOTES, version FROM pets.PETOWNER WHERE (id = ?)
    bind => [3]
[EL Fine]: sql: 2022-03-10 14:50:50.437--ClientSession(840311416)--Connection(1724151743)--SELECT id, NAME, NOTES, version FROM pets.PETOWNER WHERE (id = ?)
    bind => [4]
[EL Fine]: sql: 2022-03-10 14:50:50.438--ClientSession(840311416)--Connection(1724151743)--SELECT id, NAME, NOTES, version FROM pets.PETOWNER WHERE (id = ?)
    bind => [5]
[EL Fine]: sql: 2022-03-10 14:50:50.438--ClientSession(840311416)--Connection(1724151743)--SELECT id, NAME, NOTES, version FROM pets.PETOWNER WHERE (id = ?)
    bind => [6]
[EL Fine]: sql: 2022-03-10 14:50:50.438--ClientSession(840311416)--Connection(1724151743)--SELECT id, NAME, NOTES, version FROM pets.PETOWNER WHERE (id = ?)
    bind => [7]
[EL Fine]: sql: 2022-03-10 14:50:50.438--ClientSession(840311416)--Connection(1724151743)--SELECT id, NAME, NOTES, version FROM pets.PETOWNER WHERE (id = ?)
    bind => [8]
[EL Fine]: sql: 2022-03-10 14:50:50.439--ClientSession(840311416)--Connection(1724151743)--SELECT id, NAME, NOTES, version FROM pets.PETOWNER WHERE (id = ?)
    bind => [9]
[EL Fine]: sql: 2022-03-10 14:50:50.439--ClientSession(840311416)--Connection(1724151743)--SELECT id, NAME, NOTES, version FROM pets.PETOWNER WHERE (id = ?)
    bind => [10]
[EL Fine]: sql: 2022-03-10 14:50:50.439--ClientSession(840311416)--Connection(1724151743)--SELECT id, NAME, NOTES, version FROM pets.PETOWNER WHERE (id = ?)
    bind => [11]
[EL Fine]: sql: 2022-03-10 14:50:50.44--ClientSession(840311416)--Connection(1724151743)--SELECT id, NAME, NOTES, version FROM pets.PETOWNER WHERE (id = ?)
    bind => [12]
[EL Fine]: sql: 2022-03-10 14:50:50.44--ClientSession(840311416)--Connection(1724151743)--SELECT id, NAME, NOTES, version FROM pets.PETOWNER WHERE (id = ?)
    bind => [13]

is there any config/setting inside Apache Isis to not make those queries? since from the first query I assume we already got everything right?

  1. We still see delay even without those queries. So to solve the issue, we introduced a DTO class as view model to decouple domain entities from the list results

DTO class:

@DomainObject(nature = Nature.VIEW_MODEL,logicalTypeName = "cps.PetOwnerDtoViewModel")
@XmlRootElement(name = "PetOwnerDtoViewModel")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(
        propOrder = {
                "name",
                "notes"
        }
)
public class PetOwnerDto {
        private String name;
        private String notes;

...(constructor and getter setter)
}

and wrapped a list of DTOs into another viewmodel because we need to add action against collection later. (as suggested here ISIS: Moving from deprecated @Action(invokeOn=...) to @Action(associateWith=...) )

@DomainObject(nature = Nature.VIEW_MODEL,logicalTypeName = "cps.PetOwnersViewModel")
@XmlRootElement(name = "PetOwnersViewModel")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(
        propOrder = {
                "petOwnerList"
        }
)
@NoArgsConstructor(access = AccessLevel.PUBLIC)
public class PetOwnersViewModel {
    public String title() {
        return "Owners";
    }

    @XmlElementWrapper
    @XmlElement(name = "petOwnerList")
    @Getter
    @Setter
    @CollectionLayout(paged = 5)
    protected List<PetOwnerDto> petOwnerList = new LinkedList<>();

    public PetOwnersViewModel(List<PetOwnerDto> results) {
        this.petOwnerList = results;
    }

}

And we created a new action to return PetOwnerViewModel:

    @Action(semantics = SemanticsOf.SAFE)
    @ActionLayout(bookmarking = BookmarkPolicy.AS_ROOT)
    public PetOwnersViewModel listAllDto() {
        List<PetOwner> petOwnerList = petOwnerRepository.findAll();
        LinkedList<PetOwnerDto> petOwnerDtos = new LinkedList<>();
        for (PetOwner p : petOwnerList) {
            petOwnerDtos.add(new PetOwnerDto(p));
        }
        return new PetOwnersViewModel(petOwnerDtos);
    }

This way there is only one query goes out to db, no extra queries are found. Then we loaded the db with 1000 pet owners. with @CollectionLayout(paged = 5) in place, the delay is still there but acceptable, but if we click "show all", it takes 20 seconds to show all 1000 rows' data. Is there any reason this operation takes so long? Since all the needed data is already pulled from db right?

Thanks, hope anyone can help!

Formally this is not an answer (just a comment):

Thanks for reporting your observations here: I did open a Jira ticket for further investigation:

https://issues.apache.org/jira/browse/ISIS-2973

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM