将AbstractLobType迁移到Hibernate 4和Spring 3.2

时间:2013-12-09 15:28:52

标签: spring hibernate jira

我目前正在使用Hibernate 3和Spring 3.0。我想迁移到Hibernate 4和Spring 3.2。我正在使用AbstractLobType的子类来实现从InputStream映射到数据库(MySQL LONGBLOB)的UserType:

import java.io.InputStream;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;

import org.hibernate.HibernateException;
import org.springframework.jdbc.support.lob.LobCreator;
import org.springframework.jdbc.support.lob.LobHandler;
import org.springframework.orm.hibernate3.support.AbstractLobType;

public class BlobUserType extends AbstractLobType {

public int[] sqlTypes() {
    return new int[] { Types.BLOB };
}

public Class returnedClass() {
    return InputStream.class;
}

@Override
protected Object nullSafeGetInternal(ResultSet rs, String[] names, Object owner, LobHandler lobHandler)
throws SQLException, HibernateException {
    return lobHandler.getBlobAsBinaryStream(rs, names[0]);
}

@Override
protected void nullSafeSetInternal(PreparedStatement ps, int index, Object value, LobCreator lobCreator)
throws SQLException, HibernateException {
    if (value != null) {
        lobCreator.setBlobAsBinaryStream(ps, index, (InputStream) value, -1);
    } else {
        lobCreator.setBlobAsBytes(ps, index, null);
    }
}
}

由于AbstractLobType位于hibernate3,我不应再使用它了,但替代方案是什么?

我在春季项目上看过this JIRA issue,但它根本没有帮助我。

这是hibernate映射:

<class name="SoundNotification" table="SoundNotification" entity-name="SoundNotificationWithData">
    <id name="m_id" type="int" column="id" unsaved-value="-1">
        <generator class="native"/>
    </id>
    <property name="m_name" column="name" unique="true" not-null="true"/>
    <property name="m_data" column="data"
              type="com.mycompany.server.common.service.persistence.impl.hibernate.usertype.BlobUserType"
              not-null="true"/>
    <property name="m_size" formula="OCTET_LENGTH(data)"/>
    <property name="m_inUse"
              formula="(select count(1) from EventTypeConfiguration etc where etc.soundNotification=id)"/>
</class>

Java类:

public class SoundNotification extends IntegerEntity
{
    private String m_name;
    private transient InputStream m_data;
    private boolean m_inUse;
    private long m_size;

   // getters and setters ...
}

使用MaterializedBlobType更新:

我的TrafficMap.hbm.xml:

<class name="TrafficMapImage" table="TrafficMapImage" entity-name="TrafficMapImageWithData">
    <id name="m_id" column="id" type="int" unsaved-value="-1">
        <generator class="native"/>
    </id>

    <property name="m_created" column="created" type="org.jadira.usertype.dateandtime.joda.PersistentDateTime"
              not-null="true"/>
    <property name="m_image" column="image"
              type="org.hibernate.type.MaterializedBlobType"
              not-null="true"/>
    <property name="m_type" column="type" not-null="true">
        <type name="com.traficon.tmsng.server.common.service.persistence.impl.hibernate.usertype.EnumUserType">
            <param name="enumClass">com.traficon.domain.map.TrafficMapImageType</param>
        </type>
    </property>
</class>

我的Spring上下文中的sessionFactory bean:

    <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="hibernateProperties">
        <value>
            hibernate.dialect=${hibernate.dialect}
            hibernate.hbm2ddl.auto=${hibernate.hbm2ddl.auto}
            hibernate.show_sql=${hibernate.show_sql}
            hibernate.jdbc.batch_size=50
            hibernate.jdbc.use_streams_for_binary=true
            hibernate.current_session_context_class=com.traficon.tmsng.server.common.spring.TransactionAwareSessionContext
        </value>
    </property>
    <property name="mappingResources">
        <list>
            <value>hibernate/authentication.hbm.xml</value>
            <value>hibernate/SystemPrefs.hbm.xml</value>
            <value>hibernate/Detector.hbm.xml</value>
            <value>hibernate/filters.hbm.xml</value>
            <value>hibernate/EventTypeConfiguration.hbm.xml</value>
            <value>hibernate/Scenario.hbm.xml</value>
            <value>hibernate/RunningScenario.hbm.xml</value>
            <value>hibernate/StorePoint.hbm.xml</value>
            <value>hibernate/OfflineNetwork.hbm.xml</value>
            <value>hibernate/Characteristics.hbm.xml</value>
            <value>hibernate/EventType.hbm.xml</value>
            <value>hibernate/EventStore.hbm.xml</value>
            <value>hibernate/IntervalDataMessage.hbm.xml</value>
            <value>hibernate/IntegrationPeriodConstraints.hbm.xml</value>
            <value>hibernate/Media.hbm.xml</value>
            <value>hibernate/TrafficMap.hbm.xml</value>
            <value>hibernate/CommentLibrary.hbm.xml</value>
            <value>hibernate/CommentHistory.hbm.xml</value>
            <value>hibernate/Dashboard.hbm.xml</value>
        </list>
    </property>
    <property name="entityInterceptor">
        <bean class="com.traficon.tmsng.server.common.service.persistence.impl.hibernate.RollbackReintializerInterceptor"
              scope="prototype"/>
    </property>
</bean>

日志记录输出:

[WARNING] [talledLocalContainer] INFO: Initializing Spring root WebApplicationContext
[INFO] [talledLocalContainer] 13 Dec 2013 13:54:10,525 [main] INFO  hibernate.annotations.common.Version  - HCANN000001: Hibernate Commons Annotations {4.0.2.Final}
[INFO] [talledLocalContainer] 13 Dec 2013 13:54:10,537 [main] INFO  org.hibernate.Version  - HHH000412: Hibernate Core {4.2.7.Final}
[INFO] [talledLocalContainer] 13 Dec 2013 13:54:10,544 [main] INFO  org.hibernate.cfg.Environment  - HHH000205: Loaded properties from resource hibernate.properties: {hibernate.jdbc.use_streams_for_binary=true, hibernate.bytecode.use_reflection_optimizer=false}
[INFO] [talledLocalContainer] 13 Dec 2013 13:54:10,545 [main] INFO  org.hibernate.cfg.Environment  - HHH000407: Using java.io streams to persist binary types
[INFO] [talledLocalContainer] 13 Dec 2013 13:54:10,546 [main] INFO  org.hibernate.cfg.Environment  - HHH000021: Bytecode provider name : javassist
[INFO] [talledLocalContainer] 13 Dec 2013 13:54:12,302 [main] INFO  org.hibernate.dialect.Dialect  - HHH000400: Using dialect: org.hibernate.dialect.MySQL5InnoDBDialect

...

[INFO] [talledLocalContainer] 13 Dec 2013 14:06:12,136 [http-8080-4] INFO  hibernate.event.internal.DefaultLoadEventListener  - HHH000327: Error performing load command : org.hibernate.PropertyAccessException: could not set a field value by reflection setter of com.traficon.domain.map.TrafficMapImage.m_image
[WARNING] [talledLocalContainer] Dec 13, 2013 2:06:12 PM org.apache.catalina.core.StandardWrapperValve invoke
[WARNING] [talledLocalContainer] SEVERE: Servlet.service() for servlet mediaServlet threw exception
[WARNING] [talledLocalContainer] java.lang.IllegalArgumentException: Can not set java.io.InputStream field com.traficon.domain.map.TrafficMapImage.m_image to [B
[WARNING] [talledLocalContainer]    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:164)
[WARNING] [talledLocalContainer]    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:168)
[WARNING] [talledLocalContainer]    at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:81)
[WARNING] [talledLocalContainer]    at java.lang.reflect.Field.set(Field.java:741)
[WARNING] [talledLocalContainer]    at org.hibernate.property.DirectPropertyAccessor$DirectSetter.set(DirectPropertyAccessor.java:139)
[WARNING] [talledLocalContainer]    at org.hibernate.tuple.entity.AbstractEntityTuplizer.setPropertyValues(AbstractEntityTuplizer.java:710)
[WARNING] [talledLocalContainer]    at org.hibernate.tuple.entity.PojoEntityTuplizer.setPropertyValues(PojoEntityTuplizer.java:379)
[WARNING] [talledLocalContainer]    at org.hibernate.persister.entity.AbstractEntityPersister.setPropertyValues(AbstractEntityPersister.java:4523)
[WARNING] [talledLocalContainer]    at org.hibernate.engine.internal.TwoPhaseLoad.doInitializeEntity(TwoPhaseLoad.java:186)
[WARNING] [talledLocalContainer]    at org.hibernate.engine.internal.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:137)
[WARNING] [talledLocalContainer]    at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:1108)
[WARNING] [talledLocalContainer]    at org.hibernate.loader.Loader.processResultSet(Loader.java:964)
[WARNING] [talledLocalContainer]    at org.hibernate.loader.Loader.doQuery(Loader.java:911)
[WARNING] [talledLocalContainer]    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:342)
[WARNING] [talledLocalContainer]    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:312)
[WARNING] [talledLocalContainer]    at org.hibernate.loader.Loader.loadEntity(Loader.java:2121)
[WARNING] [talledLocalContainer]    at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:82)
[WARNING] [talledLocalContainer]    at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:72)
[WARNING] [talledLocalContainer]    at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:3941)
[WARNING] [talledLocalContainer]    at org.hibernate.event.internal.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:460)
[WARNING] [talledLocalContainer]    at org.hibernate.event.internal.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:429)
[WARNING] [talledLocalContainer]    at org.hibernate.event.internal.DefaultLoadEventListener.load(DefaultLoadEventListener.java:206)
[WARNING] [talledLocalContainer]    at org.hibernate.event.internal.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:246)
[WARNING] [talledLocalContainer]    at org.hibernate.event.internal.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:150)
[WARNING] [talledLocalContainer]    at org.hibernate.internal.SessionImpl.fireLoad(SessionImpl.java:1098)
[WARNING] [talledLocalContainer]    at org.hibernate.internal.SessionImpl.access$2000(SessionImpl.java:175)
[WARNING] [talledLocalContainer]    at org.hibernate.internal.SessionImpl$IdentifierLoadAccessImpl.load(SessionImpl.java:2482)
[WARNING] [talledLocalContainer]    at org.hibernate.internal.SessionImpl.get(SessionImpl.java:998)
[WARNING] [talledLocalContainer]    at com.traficon.tmsng.server.common.service.persistence.impl.hibernate.HibernateTrafficMapRepository.getTrafficMapImageWithData_aroundBody6(HibernateTrafficMapRepository.java:176)
[WARNING] [talledLocalContainer]    at com.traficon.tmsng.server.common.service.persistence.impl.hibernate.HibernateTrafficMapRepository$AjcClosure7.run(HibernateTrafficMapRepository.java:1)
[WARNING] [talledLocalContainer]    at org.springframework.transaction.aspectj.AbstractTransactionAspect.ajc$around$org_springframework_transaction_aspectj_AbstractTransactionAspect$1$2a73e96cproceed(AbstractTransactionAspect.aj:59)
[WARNING] [talledLocalContainer]    at org.springframework.transaction.aspectj.AbstractTransactionAspect$AbstractTransactionAspect$1.proceedWithInvocation(AbstractTransactionAspect.aj:65)
[WARNING] [talledLocalContainer]    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:260)
[WARNING] [talledLocalContainer]    at org.springframework.transaction.aspectj.AbstractTransactionAspect.ajc$around$org_springframework_transaction_aspectj_AbstractTransactionAspect$1$2a73e96c(AbstractTransactionAspect.aj:63)
[WARNING] [talledLocalContainer]    at com.traficon.tmsng.server.common.service.persistence.impl.hibernate.HibernateTrafficMapRepository.getTrafficMapImageWithData(HibernateTrafficMapRepository.java:173)
[WARNING] [talledLocalContainer]    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[WARNING] [talledLocalContainer]    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
[WARNING] [talledLocalContainer]    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[WARNING] [talledLocalContainer]    at java.lang.reflect.Method.invoke(Method.java:606)
[WARNING] [talledLocalContainer]    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
[WARNING] [talledLocalContainer]    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
[WARNING] [talledLocalContainer]    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
[WARNING] [talledLocalContainer]    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:155)
[WARNING] [talledLocalContainer]    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
[WARNING] [talledLocalContainer]    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:91)
[WARNING] [talledLocalContainer]    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
[WARNING] [talledLocalContainer]    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
[WARNING] [talledLocalContainer]    at com.sun.proxy.$Proxy39.getTrafficMapImageWithData(Unknown Source)
[WARNING] [talledLocalContainer]    at com.traficon.tmsng.server.web.mvc.DownloadTrafficMapImageController.onSubmit(DownloadTrafficMapImageController.java:40)
[WARNING] [talledLocalContainer]    at org.springframework.web.servlet.mvc.SimpleFormController.processFormSubmission(SimpleFormController.java:272)
[WARNING] [talledLocalContainer]    at org.springframework.web.servlet.mvc.AbstractFormController.handleRequestInternal(AbstractFormController.java:268)
[WARNING] [talledLocalContainer]    at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:153)
[WARNING] [talledLocalContainer]    at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:48)
[WARNING] [talledLocalContainer]    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925)
[WARNING] [talledLocalContainer]    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
[WARNING] [talledLocalContainer]    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936)
[WARNING] [talledLocalContainer]    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:827)
[WARNING] [talledLocalContainer]    at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
[WARNING] [talledLocalContainer]    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812)
[WARNING] [talledLocalContainer]    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
[WARNING] [talledLocalContainer]    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
[WARNING] [talledLocalContainer]    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
[WARNING] [talledLocalContainer]    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
[WARNING] [talledLocalContainer]    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
[WARNING] [talledLocalContainer]    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
[WARNING] [talledLocalContainer]    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
[WARNING] [talledLocalContainer]    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:568)
[WARNING] [talledLocalContainer]    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
[WARNING] [talledLocalContainer]    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
[WARNING] [talledLocalContainer]    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845)
[WARNING] [talledLocalContainer]    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
[WARNING] [talledLocalContainer]    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
[WARNING] [talledLocalContainer]    at java.lang.Thread.run(Thread.java:744)
[WARNING] [talledLocalContainer]

3 个答案:

答案 0 :(得分:0)

理论上,如果你想为你的Blob使用MaterializedBlobType,你应该使用hibernate提供的InputStream,然后将以下属性添加到你的hibernate配置

hibernate.jdbc.use_streams_for_binary=true

这将指示MaterializedBlobType使用InputStream代替byte[]

答案 1 :(得分:0)

我最终创建了自己的用户类型,可以在Blob和InputStream之间进行转换:

import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.usertype.UserType;

import java.io.InputStream;
import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;

public class BlobUserType implements UserType
{
// ------------------------ INTERFACE METHODS ------------------------

// --------------------- Interface UserType ---------------------

    @Override
    public int[] sqlTypes()
    {
        return new int[]{Types.BLOB};
    }

    @Override
    public Class returnedClass()
    {
        return InputStream.class;
    }

    @Override
    public boolean equals( Object x, Object y ) throws HibernateException
    {
        boolean result;
        if (x == y)
        {
            result = true;
        }
        else if (x == null || y == null)
        {
            result = false;
        }
        else
        {
            result = x.equals( y );
        }
        return result;
    }

    @Override
    public int hashCode( Object x ) throws HibernateException
    {
        return x.hashCode();
    }

    @Override
    public Object nullSafeGet( ResultSet rs, String[] names, SessionImplementor session, Object owner ) throws HibernateException, SQLException
    {
        return rs.getBlob( names[0] ).getBinaryStream();
    }

    @Override
    public void nullSafeSet( PreparedStatement st, Object value, int index, SessionImplementor session ) throws HibernateException, SQLException
    {
        if( value != null )
        {
            InputStream inputStream = (InputStream)value;
            st.setBlob( index, inputStream );
        }
        else
        {
            st.setNull( index, Types.BLOB );
        }
    }

    @Override
    public Object deepCopy( Object value ) throws HibernateException
    {
        return value;
    }

    @Override
    public boolean isMutable()
    {
        return false;
    }

    @Override
    public Serializable disassemble( Object value ) throws HibernateException
    {
        return null;
    }

    @Override
    public Object assemble( Serializable cached, Object owner ) throws HibernateException
    {
        return null;
    }

    @Override
    public Object replace( Object original, Object target, Object owner ) throws HibernateException
    {
        return original;
    }
}

似乎可以正常加载并将我的实体保存到数据库中。

答案 2 :(得分:0)

你不应该使用AbstractLobType,因为它正如你所说的那样在hibernate 3中。

您可以创建自己的UserType以在Blob和InputStream之间进行转换。但是,如果要将现有数据从Hibernate 3迁移到4,则代码​​将无法运行:

BlobSerializableType的格式还包含标题信息,如下所示:

¬ít{“userServices”:[{“accountStatus”:“PendingTermsAndConditions”,“serviceIdentifier”:“SNG”}] ...}]}

您的代码将工作(读取,写入)到没有标题的格式: { “userServices”:[{ “accountStatus”: “PendingTermsAndConditions”, “serviceIdentifier”: “SNG”}] ...}]}

我个人的解决方案是模拟Hibernate 3来编写和读取Blob数据,如下所示:

package com.newbay.acs.domain.hibernate;

import org.apache.commons.io.IOUtils;
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.usertype.UserType;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;

/**
 * Created by qale0001 on 21/06/2016.
 */
public class CustomMaterializedBlobType implements UserType
{
    private static final int OUTPUT_BYTE_ARRAY_INITIAL_SIZE = 1024;

    @Override
    public int[] sqlTypes()
    {
        return new int[]{Types.BLOB};
    }

    @Override
    public Class returnedClass()
    {
        return String.class;
    }

    @Override
    public boolean equals(Object x, Object y) throws HibernateException {
        boolean result;
        if (x == y)
        {
            result = true;
        }
        else if (x == null || y == null)
        {
            result = false;
        }
        else
        {
            result = x.equals( y );
        }
        return result;
    }

    @Override
    public int hashCode(Object x) throws HibernateException {
        return x.hashCode();
    }

    @Override
    public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner)
            throws HibernateException, SQLException {
        java.sql.Blob blob = rs.getBlob( names[0] );
        InputStream is = blob.getBinaryStream();

        if (is != null) {
            try {
                ObjectInputStream ois = new ObjectInputStream(is);
                try {
                    return ois.readObject();
                } catch (ClassNotFoundException ex) {
                    throw new HibernateException("Could not deserialize BLOB contents", ex);
                } finally {
                    ois.close();
                }
            } catch (IOException ex) {
                throw new HibernateException("Could not deserialize BLOB contents", ex);
            }
        }
        else {
            return null;
        }
    }

    @Override
    public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session) throws HibernateException, SQLException {
        if( value != null )
        {
            ByteArrayOutputStream baos = new ByteArrayOutputStream(OUTPUT_BYTE_ARRAY_INITIAL_SIZE);
            try {
                ObjectOutputStream oos = new ObjectOutputStream(baos);
                try {
                    oos.writeObject(value);
                    oos.flush();
                    InputStream is = new ByteArrayInputStream(baos.toByteArray());
                    st.setBlob(index, is);
                }
                finally {
                    oos.close();
                }
            } catch (IOException ex) {
                throw new HibernateException("Could not serialize BLOB contents", ex);
            }
        }
        else
        {
            st.setNull( index, Types.BLOB );
        }
    }

    @Override
    public Object deepCopy(Object value) throws HibernateException {
        return value;
    }

    @Override
    public boolean isMutable() {
        return false;
    }

    @Override
    public Serializable disassemble(Object value) throws HibernateException {
        return null;
    }

    @Override
    public Object assemble(Serializable cached, Object owner) throws HibernateException {
        return null;
    }

    @Override
    public Object replace(Object original, Object target, Object owner) throws HibernateException {
        return original;
    }

}