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.IOException; 020import java.io.Serializable; 021import java.sql.PreparedStatement; 022import java.sql.ResultSet; 023import java.sql.SQLException; 024import javax.transaction.TransactionManager; 025 026import org.apache.commons.logging.Log; 027import org.apache.commons.logging.LogFactory; 028import org.hibernate.HibernateException; 029import org.hibernate.usertype.UserType; 030import org.hibernate.util.EqualsHelper; 031 032import org.springframework.jdbc.support.lob.LobCreator; 033import org.springframework.jdbc.support.lob.LobCreatorUtils; 034import org.springframework.jdbc.support.lob.LobHandler; 035 036/** 037 * Abstract base class for Hibernate UserType implementations that map to LOBs. 038 * Retrieves the LobHandler to use from LocalSessionFactoryBean at config time. 039 * 040 * <p>For writing LOBs, either an active Spring transaction synchronization 041 * or an active JTA transaction (with "jtaTransactionManager" specified on 042 * LocalSessionFactoryBean or a Hibernate TransactionManagerLookup configured 043 * through the corresponding Hibernate property) is required. 044 * 045 * <p>Offers template methods for setting parameters and getting result values, 046 * passing in the LobHandler or LobCreator to use. 047 * 048 * @author Juergen Hoeller 049 * @since 1.2 050 * @see org.springframework.jdbc.support.lob.LobHandler 051 * @see org.springframework.jdbc.support.lob.LobCreator 052 * @see org.springframework.orm.hibernate3.LocalSessionFactoryBean#setLobHandler 053 * @see org.springframework.orm.hibernate3.LocalSessionFactoryBean#setJtaTransactionManager 054 * @deprecated as of Spring 4.3, in favor of Hibernate 4.x/5.x 055 */ 056@Deprecated 057public abstract class AbstractLobType implements UserType { 058 059 protected final Log logger = LogFactory.getLog(getClass()); 060 061 private final LobHandler lobHandler; 062 063 private final TransactionManager jtaTransactionManager; 064 065 066 /** 067 * Constructor used by Hibernate: fetches config-time LobHandler and 068 * config-time JTA TransactionManager from LocalSessionFactoryBean. 069 * @see org.springframework.orm.hibernate3.LocalSessionFactoryBean#getConfigTimeLobHandler 070 * @see org.springframework.orm.hibernate3.LocalSessionFactoryBean#getConfigTimeTransactionManager 071 */ 072 protected AbstractLobType() { 073 this(org.springframework.orm.hibernate3.LocalSessionFactoryBean.getConfigTimeLobHandler(), 074 org.springframework.orm.hibernate3.LocalSessionFactoryBean.getConfigTimeTransactionManager()); 075 } 076 077 /** 078 * Constructor used for testing: takes an explicit LobHandler 079 * and an explicit JTA TransactionManager (can be {@code null}). 080 */ 081 protected AbstractLobType(LobHandler lobHandler, TransactionManager jtaTransactionManager) { 082 this.lobHandler = lobHandler; 083 this.jtaTransactionManager = jtaTransactionManager; 084 } 085 086 087 /** 088 * This implementation returns false. 089 */ 090 @Override 091 public boolean isMutable() { 092 return false; 093 } 094 095 /** 096 * This implementation delegates to the Hibernate EqualsHelper. 097 * @see org.hibernate.util.EqualsHelper#equals 098 */ 099 @Override 100 public boolean equals(Object x, Object y) throws HibernateException { 101 return EqualsHelper.equals(x, y); 102 } 103 104 /** 105 * This implementation returns the hashCode of the given objectz. 106 */ 107 @Override 108 public int hashCode(Object x) throws HibernateException { 109 return x.hashCode(); 110 } 111 112 /** 113 * This implementation returns the passed-in value as-is. 114 */ 115 @Override 116 public Object deepCopy(Object value) throws HibernateException { 117 return value; 118 } 119 120 /** 121 * This implementation returns the passed-in value as-is. 122 */ 123 @Override 124 public Serializable disassemble(Object value) throws HibernateException { 125 return (Serializable) value; 126 } 127 128 /** 129 * This implementation returns the passed-in value as-is. 130 */ 131 @Override 132 public Object assemble(Serializable cached, Object owner) throws HibernateException { 133 return cached; 134 } 135 136 /** 137 * This implementation returns the passed-in original as-is. 138 */ 139 @Override 140 public Object replace(Object original, Object target, Object owner) throws HibernateException { 141 return original; 142 } 143 144 145 /** 146 * This implementation delegates to nullSafeGetInternal, 147 * passing in the LobHandler of this type. 148 * @see #nullSafeGetInternal 149 */ 150 @Override 151 @Deprecated 152 public final Object nullSafeGet(ResultSet rs, String[] names, Object owner) 153 throws HibernateException, SQLException { 154 155 if (this.lobHandler == null) { 156 throw new IllegalStateException("No LobHandler found for configuration - " + 157 "lobHandler property must be set on LocalSessionFactoryBean"); 158 } 159 160 try { 161 return nullSafeGetInternal(rs, names, owner, this.lobHandler); 162 } 163 catch (IOException ex) { 164 throw new HibernateException("I/O errors during LOB access", ex); 165 } 166 } 167 168 /** 169 * This implementation delegates to nullSafeSetInternal, 170 * passing in a transaction-synchronized LobCreator for the 171 * LobHandler of this type. 172 * @see #nullSafeSetInternal 173 */ 174 @Override 175 @Deprecated 176 public final void nullSafeSet(PreparedStatement st, Object value, int index) 177 throws HibernateException, SQLException { 178 179 if (this.lobHandler == null) { 180 throw new IllegalStateException("No LobHandler found for configuration - " + 181 "lobHandler property must be set on LocalSessionFactoryBean"); 182 } 183 184 LobCreator lobCreator = this.lobHandler.getLobCreator(); 185 try { 186 nullSafeSetInternal(st, index, value, lobCreator); 187 } 188 catch (IOException ex) { 189 throw new HibernateException("I/O errors during LOB access", ex); 190 } 191 LobCreatorUtils.registerTransactionSynchronization(lobCreator, this.jtaTransactionManager); 192 } 193 194 /** 195 * Template method to extract a value from the given result set. 196 * @param rs the ResultSet to extract from 197 * @param names the column names 198 * @param owner the containing entity 199 * @param lobHandler the LobHandler to use 200 * @return the extracted value 201 * @throws SQLException if thrown by JDBC methods 202 * @throws IOException if thrown by streaming methods 203 * @throws HibernateException in case of any other exceptions 204 */ 205 protected abstract Object nullSafeGetInternal( 206 ResultSet rs, String[] names, Object owner, LobHandler lobHandler) 207 throws SQLException, IOException, HibernateException; 208 209 /** 210 * Template method to set the given parameter value on the given statement. 211 * @param ps the PreparedStatement to set on 212 * @param index the statement parameter index 213 * @param value the value to set 214 * @param lobCreator the LobCreator to use 215 * @throws SQLException if thrown by JDBC methods 216 * @throws IOException if thrown by streaming methods 217 * @throws HibernateException in case of any other exceptions 218 */ 219 protected abstract void nullSafeSetInternal( 220 PreparedStatement ps, int index, Object value, LobCreator lobCreator) 221 throws SQLException, IOException, HibernateException; 222 223}