Listening for proxy replacement

Sorry for using the wrong words in the topic title, what I want to do is get notified

   a) when a proxy is created instead of fetching an entity from the database
   b) when the proxy is replaced with the entity it represents

The purpose is to log how long each proxy lives, as we suspect some of our lazy associations are fetched straight away. Ideally, it would be similar to EventListener, say onProxyCreation(Object proxy, Class entityClass, Serializable id) and onProxyReplacement(Object proxy, Object entity, Serializable id).
We could then use this to log a warning when a proxy lives for less than eg 100ms.

We are currently using Hibernate 5.6 without JPA (ie using Session interface).

I think you could try to achieve that by implement a custom ProxyFactory which you can provide yourself through a Hibernate service by registering a org.hibernate.bytecode.spi.ProxyFactoryFactory. See org.hibernate.bytecode.internal.bytebuddy.ProxyFactoryFactoryImpl for an example. I guess you’ mostly copy the existing bytebuddy implementation and just add the aspects you care about to the respective methods getProxy and org.hibernate.proxy.LazyInitializer#getImplementation().

1 Like

@beikov could you please be more specific on how to register custom ProxyFactory? I tried to find it on doc but failed.

Take a look at org.hibernate.bytecode.internal.ProxyFactoryFactoryInitiator which provides the proxy factory right now. You have to register a custom ServiceInitiator through e.g. org.hibernate.service.spi.ServiceContributor, which is a Java service loader contract.

@beikov the problem is we are using Hibernate 5.3, I can’t find ProxyFactoryFactoryInitiator under that version.

This was introduced in 5.4 via [HHH-13849] - Hibernate JIRA
For 5.3 I think you have to register a custom BytecodeProvider service which is what returns that proxy factory.

I found this on 5.3 doc which suggests 5.3 doesn’t support custom bytecode provider?
hibernate.bytecode.provider (e.g. bytebuddy (default value))

The BytecodeProvider built-in implementation flavor. Currently, only bytebuddy and javassist are valid values.

I think you should be able to register the BytecodeProvider as service, but seriously, if you want to replace such core parts of ORM, you better start getting used to digging in internals. Checkout the code base and look for usages of the types to understand how instances of the types are acquired. This way, you will find answers to your questions and also understand the ORM better.

@beikov I will dig Hibernate code. Thanks a lot for above hints.