001/*
002 * Copyright 2002-2012 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.orm.hibernate3.support;
018
019import java.io.UnsupportedEncodingException;
020import java.sql.PreparedStatement;
021import java.sql.ResultSet;
022import java.sql.SQLException;
023import java.sql.Types;
024import javax.transaction.TransactionManager;
025
026import org.springframework.jdbc.support.lob.LobCreator;
027import org.springframework.jdbc.support.lob.LobHandler;
028
029/**
030 * Hibernate UserType implementation for Strings that get mapped to BLOBs.
031 * Retrieves the LobHandler to use from LocalSessionFactoryBean at config time.
032 *
033 * <p>This is intended for the (arguably unnatural, but still common) case
034 * where character data is stored in a binary LOB. This requires encoding
035 * and decoding the characters within this UserType; see the javadoc of the
036 * {@code getCharacterEncoding()} method.
037 *
038 * <p>Can also be defined in generic Hibernate mappings, as DefaultLobCreator will
039 * work with most JDBC-compliant database drivers. In this case, the field type
040 * does not have to be BLOB: For databases like MySQL and MS SQL Server, any
041 * large enough binary type will work.
042 *
043 * @author Juergen Hoeller
044 * @since 1.2.7
045 * @see #getCharacterEncoding()
046 * @see org.springframework.orm.hibernate3.LocalSessionFactoryBean#setLobHandler
047 * @deprecated as of Spring 4.3, in favor of Hibernate 4.x/5.x
048 */
049@Deprecated
050public class BlobStringType extends AbstractLobType {
051
052        /**
053         * Constructor used by Hibernate: fetches config-time LobHandler and
054         * config-time JTA TransactionManager from LocalSessionFactoryBean.
055         * @see org.springframework.orm.hibernate3.LocalSessionFactoryBean#getConfigTimeLobHandler
056         * @see org.springframework.orm.hibernate3.LocalSessionFactoryBean#getConfigTimeTransactionManager
057         */
058        public BlobStringType() {
059                super();
060        }
061
062        /**
063         * Constructor used for testing: takes an explicit LobHandler
064         * and an explicit JTA TransactionManager (can be {@code null}).
065         */
066        protected BlobStringType(LobHandler lobHandler, TransactionManager jtaTransactionManager) {
067                super(lobHandler, jtaTransactionManager);
068        }
069
070        @Override
071        public int[] sqlTypes() {
072                return new int[] {Types.BLOB};
073        }
074
075        @Override
076        public Class<?> returnedClass() {
077                return String.class;
078        }
079
080        @Override
081        protected Object nullSafeGetInternal(
082                        ResultSet rs, String[] names, Object owner, LobHandler lobHandler)
083                        throws SQLException, UnsupportedEncodingException {
084
085                byte[] bytes = lobHandler.getBlobAsBytes(rs, names[0]);
086                if (bytes != null) {
087                        String encoding = getCharacterEncoding();
088                        return (encoding != null ? new String(bytes, encoding) : new String(bytes));
089                }
090                else {
091                        return null;
092                }
093        }
094
095        @Override
096        protected void nullSafeSetInternal(
097                        PreparedStatement ps, int index, Object value, LobCreator lobCreator)
098                        throws SQLException, UnsupportedEncodingException {
099
100                if (value != null) {
101                        String str = (String) value;
102                        String encoding = getCharacterEncoding();
103                        byte[] bytes = (encoding != null ? str.getBytes(encoding) : str.getBytes());
104                        lobCreator.setBlobAsBytes(ps, index, bytes);
105                }
106                else {
107                        lobCreator.setBlobAsBytes(ps, index, null);
108                }
109        }
110
111        /**
112         * Determine the character encoding to apply to the BLOB's bytes
113         * to turn them into a String.
114         * <p>Default is {@code null}, indicating to use the platform
115         * default encoding. To be overridden in subclasses for a specific
116         * encoding such as "ISO-8859-1" or "UTF-8".
117         * @return the character encoding to use, or {@code null}
118         * to use the platform default encoding
119         * @see String#String(byte[], String)
120         * @see String#getBytes(String)
121         */
122        protected String getCharacterEncoding() {
123                return null;
124        }
125
126}