hibernate/hibernate-orm · error · UnsupportedOperationException
Clobs are not cacheable
Error message
Clobs are not cacheable
What it means
NClobMutabilityPlan implements disassemble() by throwing UnsupportedOperationException because a live java.sql.NClob is a handle tied to a JDBC connection/locator and cannot be serialized into the second-level cache. disassemble runs when Hibernate builds a cache entry, so the exception appears at write time (insert/update of a cached entity, or putting a query result into the cache).
Source
Thrown at hibernate-core/src/main/java/org/hibernate/type/descriptor/java/NClobJavaType.java:49
* @author Steve Ebersole
* @author Loïc Lefèvre
*/
public class NClobJavaType extends AbstractClassJavaType<NClob> {
public static final NClobJavaType INSTANCE = new NClobJavaType();
public static class NClobMutabilityPlan implements MutabilityPlan<NClob> {
public static final NClobMutabilityPlan INSTANCE = new NClobMutabilityPlan();
public boolean isMutable() {
return false;
}
public NClob deepCopy(NClob value) {
return value;
}
public Serializable disassemble(NClob value, SharedSessionContract session) {
throw new UnsupportedOperationException( "Clobs are not cacheable" );
}
public NClob assemble(Serializable cached, SharedSessionContract session) {
throw new UnsupportedOperationException( "Clobs are not cacheable" );
}
}
public NClobJavaType() {
super( NClob.class, NClobMutabilityPlan.INSTANCE, IncomparableComparator.INSTANCE );
}
@Override
public boolean isInstance(Object value) {
return value instanceof NClob;
}
@Override
public NClob cast(Object value) {View on GitHub (pinned to fad1729dce)
Solutions
- Model the LOB in a separate, non-cached entity and reference it @OneToOne(fetch=LAZY); cache only the LOB-free aggregate
- Map the column as materialized text: @Lob @Nationalized String (String is cacheable) instead of java.sql.NClob
- Remove the entity/property from second-level caching entirely
- Verify no query cache stores entities with NClob attributes
Example fix
// before
@Entity @Cacheable
class Article {
@Id Long id;
@Nationalized java.sql.NClob body; // disassemble -> UnsupportedOperationException
}
// after
@Entity @Cacheable
class Article {
@Id Long id;
@OneToOne(fetch = FetchType.LAZY) ArticleBody body; // separate table
}
@Entity
class ArticleBody {
@Id Long id;
@Nationalized @Lob String body; // materialized, cacheable sibling Defensive patterns
Strategy: validation
Validate before calling
// startup check: refuse caching entities with live LOB fields
for (var binding : sessionFactory.getMetamodel().getEntities()) {
for (var attr : binding.getAttributes()) {
if (java.sql.NClob.class.isAssignableFrom(attr.getJavaType())
&& binding.getJpaMetamodel()... /* entity is @Cacheable */) {
throw new IllegalStateException("Cached entity " + binding.getName() + " has NClob attribute " + attr.getName());
}
}
} Type guard
static boolean isCacheableJavaType(Class<?> t) {
return !(java.sql.NClob.class.isAssignableFrom(t) || java.sql.Clob.class.isAssignableFrom(t) || java.sql.Blob.class.isAssignableFrom(t));
} Try / catch
catch (UnsupportedOperationException e) {
if ("Clobs are not cacheable".equals(e.getMessage()))
throw new IllegalStateException("Remove NClob attributes from cached entities or map them as String", e);
throw e;
} Prevention
- Never annotate LOB-bearing entities with @Cacheable
- Model LOBs in separate non-cached entities referenced @OneToOne(lazy)
- Map LOB columns as materialized String/byte[] when caching is required
When it happens
Trigger: An entity with a java.sql.NClob (or @Nationalized LOB) attribute is annotated @Cacheable or covered by a @Cache(...) region; a collection or query cache entry includes such a value; hibernate.cache enabled globally and the entity gets cached on flush
Common situations: Adding caching annotations to legacy entities that carry LOB fields; moving LOB content from String columns to NClob columns on already-cached entities; enabling query caching on queries selecting LOB entities
Related errors
- Unknown access type [
- Tried to assemble a different subclass instance
- Caching was not configured for entity:
- Caching was not configured for entity natural id:
- Caching was not configured for collection:
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/cd1b42eef0ef3cd4.
Report an issue: GitHub.