Performance penalty calling Throwable.getStackTrace()
Description
Environment
Attachments
relates to
Activity

Gunnar Morling October 18, 2017 at 10:13 AM
See the related discussion on beanvalidation-dev, the motivation for having a JPA-aware resolver by default is that one doesn't want to trigger loading of lazy references also during validation in the REST/service layer etc. Your best option is to use a custom resolver which always returns true and, once is released, you could disable the caching to get some further perf improvement.
I'm going to close this issue, as there's nothing we can do otherwise. Thanks!

Aritz Bastida October 6, 2017 at 12:37 PM
Thanks for your detailed explanations. I guess we can close this issue

Guillaume Smet October 6, 2017 at 11:33 AM
I agree the current situation is far from ideal.
For history, here is what EclipseLink does: http://grepcode.com/file/repo1.maven.org/maven2/org.eclipse.persistence/eclipselink/2.6.0/org/eclipse/persistence/internal/jpa/metadata/listeners/BeanValidationListener.java .
I'm not sure if their TraversableResolver
internals are such a good idea as I don't think what they did will work when cascading to another entity embedded in a given one. But using a specific TraversableResolver
is definitely a good idea when dealing with JPA, thus allowing a more simple TraversableResolver
to be used in the other cases. Well, with HV, it leads to use a suboptimal one unfortunately for all the other objects as JPA is in the classpath...
I tend to agree that maybe it was not such a good idea to include this in the BV spec. The JPA implementations are better placed to do the right thing as they have access to better qualified information and the validation is triggered by them so they can adjust the TraversableResolver
.
interested in your thoughts on this.

Aritz Bastida October 6, 2017 at 10:17 AM
Thanks for the quick response, Guillaume.
I just created a DtoTraversableResolver, which was easy enough
It's a bit of a shame that the Bean Validation spec defines the use of JPATraversableResolver in such a way, without any other utility to request whether the entity to be validated is a domain one or a JPA one. Indeed, it's quite ironic that, as just found out while debugging, Eclipselink ignores that resolver and uses its own one (AutomaticLifecycleValidationTraversableResolver); so in the end JPATraversableResolver is only used with the entities that are not JPA-related... o_o
Anyway, as you pointed out, the performance penalty is in the Weblogic code, not Hibernate Validator, so I will open a ticket there too. And I guess we can close this one (and maybe take the insight above as a suggestion for further revisions of the BV spec).
Thanks!

Guillaume Smet October 6, 2017 at 9:38 AM
Hi ,
Thanks for the very detailed report.
Unfortunately, I don't think there's much we can do:
the JPA API doesn't give us access to the
ValidationMode
. And even if it did, it's per persistence unit and I don't think we have a way to get the PersistenceUnit managing an entity from the API.the code in WebLogic looks very suboptimal and there's nothing we can do about it. Maybe you can try opening a support case? This code should definitely be made as fast as possible as it's called for every property.
We don't have much of a choice anyway as the behavior of the JPATraversableResolver
is defined by the Bean Validation spec and is triggered by the presence of JPA in the classpath.
I thought maybe we could try to determine if an object is an entity before triggering this behavior but unfortunately, I don't see anything in the JPA API to do so.
That being said, as it seems you are stating you don't use validation on your entities, my advice would be to define a custom TraversableResolver
returning true for both methods. You can do so either via the programmatic API or via the validation.xml configuration file.
Do you see anything else we could do? If not I'm going to close this issue.
Details
Details
Assignee

Reporter

Bug Testcase Reminder (view)
Bug reports should generally be accompanied by a test case!
Bug Testcase Reminder (edit)
Bug reports should generally be accompanied by a test case!
Participants



A bit of context first: we are developing a Spring-based web service (SOAP) application, backed by a database. We perform bean validation just before calling the @Service layer, to verify that input data conforms to the service contract. We are not validating JPA entities, because we already have check constraints in the database.
During a profiling session with Dynatrace/Java Mission Control, we have found that an approximate 10% of the CPU time is spent in Throwable.getStackTrace(), which is heavily invoked by Hibernate Validator. Find attached some pictures.
After some analysis, we have found that this problem is mostly caused by Eclipselink, in a method called isJpa1CompatibleCaller(). Incidentally, we are not validating JPA entities, so... why spend time on checking whether the attribute can be reached or if it is jpa1-compatible?
As it appears, just because JPA 2 is in the classpath, nothing more. The validation of JPA entities can be disabled setting the "javax.persistence.validation.mode" property to NONE, but that won't disable traversing DTOs as if they were JPA entities...
I suggest that JpaTraversableResolver is used only for JPA entities, or at least can be disabled when the persistence validation is set to NONE. This suggestion is in line with another JIRA issue: https://hibernate.atlassian.net/browse/HV-1487