Closed lbilger closed 1 year ago
I also tried out changing the type of the protocol
collection to a Set
and leaving out the @Fetch
annotation, but then the processor started falling behind again. So it seems to be the loading of so many rows that requires so much time.
Not directly related, it might also be a good idea to have some setting to optionally truncate the protocol if it becomes very long.
Steps to reproduce
Expected behaviour
Data entry updates are always processed quickly.
Actual behaviour
When data entries get updated a lot, they accumulate a lot of protocol entries (about 1700 in our case, to give a feeling for the order of magnitude where we are experiencing this issue). Event processing becomes very slow then, with the event processor falling behind the others under a little load. Data entry updates take minutes to be processed by the JPA view.
Debugging this, I found that the
protocol
list of theDataEntryEntity
had more then 20.000 entries after loading from the database, containing each protocol entry that actually existed 13 times. This is due to eager initialization of thepayloadAttributes
,authorizedPrincipals
andprotocol
collections with fetch joins. The database returns the cartesian product of all the joined tables, with in our case 1authorizedPrincipal
and 13payloadAttributes
.protocol
is mapped as aList
instead of aSet
, so all those (13 * 1700) rows are added to the collection. This seems to make processing very slow, either due to the huge amount of data transferred from the database or due to processing of the large list, I don't know which it is.Adding the annotation
@Fetch(FetchMode.SELECT)
toprotocol
fixes the performance issue for us. Unfortunately, that's a vendor-specific annotation from Hibernate, but it seems we are locked to Spring and thereby Hibernate anyway.I'm not sure, though, if this deteriorates performance on the Query side, when lots of DataEntries with short
protocol
s are queried. We could consider adding the@BatchSize
annotation as well to mitigate this. But maybe the fetch mode and fetch type defined on the entity are overridden by the Criteria/Specification query anyway?