1. /*
  2. * Copyright 2002-2004 the original author or authors.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package org.springframework.orm.hibernate.support;
  17. import java.sql.PreparedStatement;
  18. import java.sql.ResultSet;
  19. import java.sql.SQLException;
  20. import java.sql.Types;
  21. import net.sf.hibernate.UserType;
  22. import net.sf.hibernate.util.EqualsHelper;
  23. import org.springframework.jdbc.support.lob.LobCreator;
  24. import org.springframework.jdbc.support.lob.LobHandler;
  25. import org.springframework.orm.hibernate.LocalSessionFactoryBean;
  26. import org.springframework.transaction.support.TransactionSynchronizationAdapter;
  27. import org.springframework.transaction.support.TransactionSynchronizationManager;
  28. /**
  29. * Hibernate UserType implementation for Strings that get mapped to CLOBs.
  30. * Retrieves the LobHandler to use from LocalSessionFactoryBean at config time.
  31. *
  32. * <p>Particularly useful for storing Strings with more than 4000 characters in an
  33. * Oracle database (only possible via CLOBs), in combination with OracleLobHandler.
  34. *
  35. * <p>Can also be defined in generic Hibernate mappings, as DefaultLobCreator will
  36. * work with most JDBC-compliant databases respectively drivers. In this case,
  37. * the field type does not have to be CLOB: For databases like MySQL and MS SQL
  38. * Server, any large enough text type will work.
  39. *
  40. * @author Juergen Hoeller
  41. * @since 12.01.2004
  42. * @see org.springframework.orm.hibernate.LocalSessionFactoryBean#setLobHandler
  43. * @see org.springframework.jdbc.support.lob.LobHandler
  44. */
  45. public class ClobStringType implements UserType {
  46. protected final LobHandler lobHandler;
  47. public ClobStringType() {
  48. this.lobHandler = LocalSessionFactoryBean.getConfigTimeLobHandler();
  49. }
  50. public int[] sqlTypes() {
  51. return new int[] {Types.CLOB};
  52. }
  53. public Class returnedClass() {
  54. return String.class;
  55. }
  56. public boolean equals(Object x, Object y) {
  57. return EqualsHelper.equals(x, y);
  58. }
  59. public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws SQLException {
  60. if (this.lobHandler == null) {
  61. throw new IllegalStateException("No LobHandler found for configuration - " +
  62. "lobHandler property must be set on LocalSessionFactoryBean");
  63. }
  64. return this.lobHandler.getClobAsString(rs, rs.findColumn(names[0]));
  65. }
  66. public void nullSafeSet(PreparedStatement st, Object value, int index) throws SQLException {
  67. if (this.lobHandler == null) {
  68. throw new IllegalStateException("No LobHandler found for configuration - " +
  69. "lobHandler property must be set on LocalSessionFactoryBean");
  70. }
  71. if (!TransactionSynchronizationManager.isSynchronizationActive()) {
  72. throw new IllegalStateException("ClobStringType requires active transaction synchronization");
  73. }
  74. LobCreator lobCreator = this.lobHandler.getLobCreator();
  75. lobCreator.setClobAsString(st, index, (String) value);
  76. TransactionSynchronizationManager.registerSynchronization(new LobCreatorSynchronization(lobCreator));
  77. }
  78. public Object deepCopy(Object value) {
  79. return value;
  80. }
  81. public boolean isMutable() {
  82. return false;
  83. }
  84. /**
  85. * Callback for resource cleanup at the end of a transaction.
  86. * Invokes LobCreator.close to clean up temporary LOBs that might have been created.
  87. * @see org.springframework.jdbc.support.lob.LobCreator#close
  88. */
  89. private static class LobCreatorSynchronization extends TransactionSynchronizationAdapter {
  90. private final LobCreator lobCreator;
  91. private LobCreatorSynchronization(LobCreator lobCreator) {
  92. this.lobCreator = lobCreator;
  93. }
  94. public void beforeCompletion() {
  95. this.lobCreator.close();
  96. }
  97. }
  98. }