How to enable load time / runtime weaving with Hibernate JPA and Spring Framework - spring

I'm using Hibernate as a JPA provider (I'm using its EntityManagerFactory instead of its SessionFactory) in a Spring Framework application. I managed to get Spring Framework's load time weaving support working, so I'm past that hurdle.
I need to enable lazy loading of byte[] and #ManyToOne properties on an entity. I understand how to instrument (weave) my entities at build time using Hibernate's ant task, but I'd like to instrument my entities at runtime instead (load time weaving). I've seen references to in on several Google search results, but no actual instructions for enabling it. What property do I need to set to instruct Hibernate that it can instrument my entities at runtime?

After considerable reading of code and debugging, I figured this out. It's a shame the Hibernate ORM documentation doesn't include this information. (To be fair, the Hibernate EntityManager documentation does, but it's not easily found. The Hibernate instructions on "Using lazy property fetching" only says, "Lazy property loading requires buildtime bytecode instrumentation." It does not mention that you can use runtime instrumentation with a Hibernate EntityManager property.)
The first thing you must do is set the "hibernate.ejb.use_class_enhancer" JPA property to "true" (String). This tells Hibernate that it may use the "application server" class transformation by calling addTransformer on the PersistenceUnitInfo instance. The "application server" class transformation is really Spring's LoadTimeWeaver. If you are using Spring's Java configuration and LocalContainerEntityManagerFactoryBean, and Hibernate is a compile-time dependency, you could use the AvailableSettings.USE_CLASS_ENHANCER constant instead of the string-literal "hibernate.ejb.use_class_enhancer" (which would make it typo-resistant).
If you are using Spring's Java configuration, there is an additional step you must take until SPR-10856 is fixed. LocalContainerEntityManagerFactoryBean's setLoadTimeWeaver method is not called automatically like it should be, so you must call it manually. In your #Configuration class, just #Inject or #Autowire a LoadTimeWeaver instance and call setLoadTimeWeaver manually when you are creating the LocalContainerEntityManagerFactoryBean.
With these steps taken, I'm now using Hibernate's runtime entity bytecode instrumentation with Spring Framework in Tomcat.

I have the similar problem. I followed the steps you have mentioned to setup the weaver successfully. I created run time entity using byte buddy with annotations. And loading this class at runt time. Created instance of the same using reflection and trying to persist. But hibernate complains as,
java.lang.IllegalArgumentException: Unknown entity:
I believe the run time entity which I created is not enhanced and hibernate is complaining the same.

Related

is there a spring property to set transaction mode to aspectJ

I need transactions for private methods and self referenced method (in a spring boot 2.7.5 application). for this documentation suggest "mode=aspectj"
Consider the use of AspectJ (see below) if you need to annotate non-public methods.
My problem all documentation about it seems to rely on xml files.
Is there a property to set this mode?
Are there other things besides needed to get #Transactional working on private methods?

Spring vs hibernate object creation

I recently learnt that in hibernate, we need a no-arg constructor in an entity because hibernate instantiates its entities via reflection:
Hibernate implementation. Are we paying the reflection penalty?
I got curious that whether it is the same case with Spring and found that Spring beans do not require a no-argument constructor mandatorily.
This brings me to the question that how does spring creates its objects if not by reflection - to which I think that Spring is a container and instantiates beans and injects dependencies on startup and it must be able to load the application beans via some classloader and hence it does not need reflection.
Then, I get back to the starting point with the question that hibernate also has my application class definition available then why does it need reflection to create its entities?
can somebody please confirm or correct my understanding and provide me an answer?

Using Spring AOP uses underneath aspectj?

Hy,
Reading a lot about Spring AOP vs AspectJ, I still have some doubts:
1.)When using Spring AOP with classes annotated with #Aspect and using "aop:aspectj-autoproxy" tag , it can be said that we are using just the annotations of aspectj or besides that it is being used AspectJ too for the weaving?
2) Its said that AspectJ has better performance because the weaving is in compilation time, it means that the target class files are physically changed inserting the aspects in them? is it not a bit aggressive?
3)It said that Spring uses proxys for AOP, so, I undertand that when you get a bean from Spring, Spring builds a proxy in memory that has already inserted the aspects in it, right?
So why is it said that when a method from your proxy bean calls other method in the proxy, the last method will not have aspects?
Thanks
1) using aspectj-autoproxy means that #Aspectannotations are recognized, but Spring proxies are still being created, see this quote from the documentation:
Do not be misled by the name of the element:
using it will result in the creation of Spring AOP proxies. The
#AspectJ style of aspect declaration is just being used here, but the
AspectJ runtime is not involved.
2) AspectJ supports load time weaving, byte code weaving and compile time weaving. There should no difference in performance, it's just a different point in time to weave the aspect in (compilation, third party jars available, class load time), see this answer for further details.
It is actually more transparent once it's set up to have the aspects weaved at these moments, with runtime proxies there are problems when a bean calls itself using this.someMethod, the aspects don't get applied because the proxies get bypassed (#Transactional/#Secured does not work, etc.).
3) Have a look at this picture from the documentation:
With runtime proxies (non AspectJ), Spring leaves the bean class untouched. What it does is it creates a proxy that either implements the same interface as the bean (JDK proxy), or if the bean implements no interface then it dynamically creates a proxy class with CGLIB (subclass of bean).
But in both cases a proxy is created that delegates the calls to the actual bean instance. So when the bean call this.methodB() from methodA, the proxy is bypassed because the call is made directly on the bean and not on the proxy.
Spring AOP can be configured with AspectJ-sytle, ie annotations are parsed to build configuration but AspectJ compiler is not used for weaving. Only a subset of AspectJ annotations and poincut definitions can be used with Spring AOP.
Maybe, but I don't know any class that has complained. However, is possible that some classes don't allow re-weaving when modified by other bytecode tools.
Inner calls are not proxied because they call on this.method() (with this = the target bean begin proxied) and not on proxy.method() so the proxy has no chances to intercept the call. However, Spring AOP proxies usually notices when a target method return this and return itself instead, so calls like builder.withColor(Color.RED).withHat(Hat.Cowboy) will work. Note that in Spring AOP there are always two classes involved: the proxy and the target.

How do I change my configuration to a different data source?

I went through the Data Access With Spring tutorial and the in memory database they use in step 3 is working. But, I'm not clear on what I need to add/change to get it to query my development (Oracle) database now?
I want to use Hibernate, do I still need this JPAConfiguration class or would I have something Hibernate specific?
Please don't just post a link to the Hibernate reference. I'm reviewing that as well, but since I'm also using Spring, it's not clear to me the proper way to load the hibernate.cfg.xml and inject the Hibernate session in that context.
Don't be blocked by the fact that the class is called JPAConfiguration. You need to understand what the class does. Note that it has the annotation #Configuration which you can use along with AnnotationConfigApplicationContext to produce a Spring bean context.
That functionality is described in the Spring documentation for The IoC container.
What you need to change is how your DataSource and EntityManagerFactory beans are created. You'll need to use a DataSource that gets Connection instances from a JDBC Driver that supports Oracle databases.

hibernate validator without using autowire

I'am currently working on a Jersey project and decided to use Hibernate validator for the parameter validations. All dependencies injected on the Endpoint classes are properly initialized. However for those dependencies in the ConstraintValidator classes, it always throw a NPE. So i followed the guide on Spring+hibernate guide and registered
bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"
and used the #Autowired annotation for the services in the ConstraintValidator class which needs to be injected.
are there side effects of using it? Is there a way to avoid the autowiring annotation in ConstraintValidator class and still injecting the values? I tried manually registering the constraintValidator class in the context as bean, adding a property reference to the service that i need, however it throws a null pointer exception.
"Hibernate Validator - JSR 303 Reference Implementation - Reference Guide" says something about portality:
Warning
Any constraint implementation relying on ConstraintValidatorFactory
behaviors specific to an implementation (dependency injection, no no-arg
constructor and so on) are not considered portable.
So, is it a bad thing? In my opinion it's not. Of course you are now coupled to the DI container (Spring) and can't easily reuse validators (e.g. when not using Spring). On the other hand, with your validators build by a Spring factory you can take full advantage of the framework and do very heavy lifting (read revision data for entities and comparison of previous states, call arbitrary services, enhance or localize validation messages, ...).
One thing you must be very careful about is that a validator's semantics is normally read-only and should not cause side-effects by calling it. For example don't accidentally flush data to the database because of some auto-flushing by invoking a (transactional) service or reading data inside your validator.

Resources