Hibernate Books

All times are UTC - 5 hours [ DST ]



Post new topic Reply to topic  [ 2 posts ] 
Author Message
 Post subject: HibernateEnhancePlugin - ClassCastException on saving entity
PostPosted: Fri Aug 11, 2017 5:26 pm 
Newbie

Joined: Fri Aug 11, 2017 3:18 pm
Posts: 1
I have some blob fields in a entity enhanced by hibernate plugin:

Obs.: jdk 8
Code:
    @Column
    @Basic(fetch = FetchType.LAZY)
    private byte[] attachment;
    @Column
    @Basic(fetch = FetchType.LAZY)
    private byte[] image;

But when I try to save(JpaRepository::save(entity)) with a SpringData Repository the following error occurs:

Stacktrace:
Code:
java.lang.ClassCastException: org.hibernate.bytecode.enhance.spi.LazyPropertyInitializer$1 cannot be cast to [B
   at org.hibernate.type.descriptor.java.PrimitiveByteArrayTypeDescriptor.areEqual(PrimitiveByteArrayTypeDescriptor.java:26)
   at org.hibernate.type.AbstractStandardBasicType.isEqual(AbstractStandardBasicType.java:197)
   at org.hibernate.type.AbstractStandardBasicType.getReplacement(AbstractStandardBasicType.java:77)
   at org.hibernate.type.AbstractStandardBasicType.replace(AbstractStandardBasicType.java:366)
   at org.hibernate.type.TypeHelper.replace(TypeHelper.java:214)
   at org.hibernate.event.internal.DefaultMergeEventListener.copyValues(DefaultMergeEventListener.java:431)
   at org.hibernate.event.internal.DefaultMergeEventListener.entityIsTransient(DefaultMergeEventListener.java:233)
   at org.hibernate.event.internal.DefaultMergeEventListener.entityIsDetached(DefaultMergeEventListener.java:301)
   at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:170)
   at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:69)
   at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:874)
   at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:860)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
   at java.lang.reflect.Method.invoke(Method.java:497)
   at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:298)
   at com.sun.proxy.$Proxy84.merge(Unknown Source)
   at org.springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:509)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
   at java.lang.reflect.Method.invoke(Method.java:497)
   at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:503)
   at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:488)
   at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:460)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
   at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:61)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
   at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
   at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281)
   at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
   at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
   at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:133)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
   at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
   at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
   at com.sun.proxy.$Proxy95.save(Unknown Source)
   [...]

When tried with @Lob, there's no exception but simply doesn't work.

I debugged and noticed that this happens with fields configured as lazy.
In the entity merge, when the fields need to be replaced between two objects (an actual to be saved and a target from merge context),
the actual have the real value (a byte array) and the target have a LazyPropertyInitializer$1 witch is tried to be casted to a byte array.

I've tried another data types, but the same casting error occurs.

I found this issue in JIRA too (https://hibernate.atlassian.net/browse/HHH-11117), but I create this topic because I think
that's is important to provide more informations about it, since I did not make the same steps (the Company/Manager relationship for example) to get the same error.

Removing @Basic(fetch = FetchType.LAZY) everything goes fine, but obviously without lazy load.

I don't think that I'm missing some property, but I can be thinking wrong.

Any fix suggestion? Or how to avoid this if a bug?

Environment:

Hibernate version: 5.2.9.Final
Springframework: 4.3.3.RELEASE

Code:
<plugin>
            <groupId>org.hibernate.orm.tooling</groupId>
            <artifactId>hibernate-enhance-maven-plugin</artifactId>
            <version>${hibernate-version}</version>
            <executions>
               <execution>
                  <configuration>
                     <enableLazyInitialization>true</enableLazyInitialization>
                  </configuration>
                  <goals>
                     <goal>enhance</goal>
                  </goals>
               </execution>
            </executions>
            <dependencies>
               <dependency>
                  <groupId>javax.transaction</groupId>
                  <artifactId>jta</artifactId>
                  <version>1.1</version>
               </dependency>
               <dependency>
                  <groupId>org.javassist</groupId>
                  <artifactId>javassist</artifactId>
                  <version>3.21.0-GA</version>
               </dependency>
            </dependencies>
         </plugin>


Thanks in advance!


Top
 Profile  
 
 Post subject: Re: HibernateEnhancePlugin - ClassCastException on saving entity
PostPosted: Sun Aug 13, 2017 2:31 am 
Hibernate Team
Hibernate Team

Joined: Thu Sep 11, 2014 2:50 am
Posts: 1588
Location: Romania
It's probably caused by HHH-11117, so you have two options:

1. In the spirit of Open-Source Software, you could try to fix the issue and send a Pull Request.
2. You can move the byte[] to a separate entity and use a FetchType.LAZY @ManuToOne instead.

_________________
If you liked my answer, you are going to love my High-Performance Java Persistence book and my blog as well.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 2 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.