I believe
HHH-9615 - Allow AttributeConverter on attributes marked as Lob Closed is not done. The test case there converts String to Integer, to represent it as Lob, but these are both basic regular types. If instead of an String you use something else (some custom Class), it doesn't seem to work. For example, here I use a class called Imagem, and convert it to a String:
@Converter
public class ImagemToString_Converter
implements AttributeConverter<Imagem, String> {
public String convertToDatabaseColumn(@Nullable Imagem attribute) {
if (attribute== null) return null;
return attribute.toString();
}
public Imagem convertToEntityAttribute(@Nullable String dbData) {
return Imagem.getInstance(dbData);
}
}
The above code works OK as long as the field is not a @Lob (which means the converter itself is correct). But as soon as I add @Lob to the field it stops working. For example:
protected Imagem fotografia;
Then, when I try to save, it should see a String (the converter gets called), but it still sees an Imagem, and then I get this:
java.lang.ClassCastException:
Imagem.Imagem cannot be cast to org.hibernate.engine.jdbc.CharacterStream
at org.hibernate.type.descriptor.sql.ClobTypeDescriptor$4$1.doBind(124)
at org.hibernate.type.descriptor.sql.BasicBinder.bind(74)
at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(277)
at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(272)
at org.hibernate.type.AbstractSingleColumnStandardBasicType.nullSafeSet(39)
at org.hibernate.persister.entity.AbstractEntityPersister.dehydrate(2646)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(2931)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(3434)
at org.hibernate.action.internal.EntityInsertAction.execute(89)
at org.hibernate.engine.spi.ActionQueue.executeActions(560)
at org.hibernate.engine.spi.ActionQueue.executeActions(434)
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(337)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(39)
at org.hibernate.internal.SessionImpl.flush(1396)
at org.hibernate.internal.SessionImpl.managedFlush(472)
at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(3132)
at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(2369)
at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(467)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(147)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.access$100(38)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(221)
at org.hibernate.engine.transaction.internal.TransactionImpl.commit(68)
at Http.Sessao.SessaoETransacaoHibernate.comitaATransaçãoCasoExistaTransaçãoAtiva(SessaoETransacaoHibernate.java:28)
at Http.Sessao.Filtro$ProcessadorDeRequest.processaRequest(Filtro.java:267)
at Http.Sessao.Filtro$ProcessadorDeRequest.access$100(Filtro.java:91)
at Http.Sessao.Filtro.doFilter(Filtro.java:594)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(206)
at org.apache.catalina.core.StandardWrapperValve.invoke(219)
at org.apache.catalina.core.StandardContextValve.invoke(106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(502)
at org.apache.catalina.core.StandardHostValve.invoke(142)
at org.apache.catalina.valves.ErrorReportValve.invoke(79)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(617)
at org.apache.catalina.core.StandardEngineValve.invoke(88)
at org.apache.catalina.connector.CoyoteAdapter.service(518)
at org.apache.coyote.http11.AbstractHttp11Processor.process(1091)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(668)
at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.doRun(2463)
at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(2452)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(61)
at java.lang.Thread.run(Thread.java:745)
If I save it to the database without @Lob, and then add the @Lob and try to open it, I get this:
org.hibernate.PropertyAccessException:
Could not set field value [com.mysql.jdbc.Clob@4b881040] value by reflection : [class ModuloADM.Usuario.Usuario.fotografia] setter of ModuloADM.Usuario.Usuario.fotografia
at org.hibernate.property.access.spi.SetterFieldImpl.set(58)
at org.hibernate.tuple.entity.AbstractEntityTuplizer.setPropertyValues(610)
at org.hibernate.tuple.entity.PojoEntityTuplizer.setPropertyValues(205)
at org.hibernate.persister.entity.AbstractEntityPersister.setPropertyValues(4618)
at org.hibernate.engine.internal.TwoPhaseLoad.doInitializeEntity(169)
at org.hibernate.engine.internal.TwoPhaseLoad.initializeEntity(125)
at org.hibernate.loader.plan.exec.process.internal.AbstractRowReader.performTwoPhaseLoad(238)
at org.hibernate.loader.plan.exec.process.internal.AbstractRowReader.finishUp(209)
at org.hibernate.loader.plan.exec.process.internal.ResultSetProcessorImpl.extractResults(133)
at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(122)
at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(86)
at org.hibernate.loader.entity.plan.AbstractLoadPlanBasedEntityLoader.load(167)
at org.hibernate.persister.entity.AbstractEntityPersister.load(4004)
at org.hibernate.event.internal.DefaultLoadEventListener.loadFromDatasource(508)
at org.hibernate.event.internal.DefaultLoadEventListener.doLoad(478)
at org.hibernate.event.internal.DefaultLoadEventListener.load(219)
at org.hibernate.event.internal.DefaultLoadEventListener.proxyOrLoad(278)
at org.hibernate.event.internal.DefaultLoadEventListener.doOnLoad(121)
at org.hibernate.event.internal.DefaultLoadEventListener.onLoad(89)
at org.hibernate.internal.SessionImpl.fireLoad(1212)
at org.hibernate.internal.SessionImpl.access$1900(204)
at org.hibernate.internal.SessionImpl$IdentifierLoadAccessImpl.doLoad(2752)
at org.hibernate.internal.SessionImpl$IdentifierLoadAccessImpl.load(2726)
at org.hibernate.internal.SessionImpl.get(1048)
at sun.reflect.NativeMethodAccessorImpl.invoke0(sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.hibernate.context.internal.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(338)
at com.sun.proxy.$Proxy64.get(com.sun.proxy.$Proxy64.get(Unknown Source)
at Objetos.Registro.Registro_Dao.busca(Registro_Dao.java:202)
...
Caused by:
java.lang.IllegalArgumentException:
Can not set Imagem.Imagem field ModuloADM.Usuario.Usuario.fotografia to com.mysql.jdbc.Clob
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(167)
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(171)
at sun.reflect.UnsafeObjectFieldAccessorImpl.set(81)
at java.lang.reflect.Field.set(Field.java:758)
at org.hibernate.property.access.spi.SetterFieldImpl.set(38)
...
|