hibernate/hibernate-orm · error · PersistenceException

Error attempting to apply AttributeConverter: " + re.getMess

Error message

Error attempting to apply AttributeConverter: " + re.getMessage()

What it means

Write-path converter wrapping from AttributeConverterInstance (Hibernate-instantiated converter): any non-PersistenceException RuntimeException thrown by convertToDatabaseColumn during flush or parameter binding is rethrown as this PersistenceException with the original failure as cause.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/type/descriptor/converter/internal/AttributeConverterInstance.java:60

		}
		catch (PersistenceException pe) {
			throw pe;
		}
		catch (RuntimeException re) {
			throw new PersistenceException( "Error attempting to apply AttributeConverter", re );
		}
	}

	@Override
	public R toRelationalValue(O domainForm) {
		try {
			return converter.convertToDatabaseColumn( domainForm );
		}
		catch (PersistenceException pe) {
			throw pe;
		}
		catch (RuntimeException re) {
			throw new PersistenceException( "Error attempting to apply AttributeConverter: " + re.getMessage(), re );
		}
	}

	@Override
	public JavaType<O> getDomainJavaType() {
		return domainJavaType;
	}

	@Override
	public JavaType<R> getRelationalJavaType() {
		return jdbcJavaType;
	}

	@Override
	public boolean equals(Object object) {
		if ( this == object ) {
			return true;
		}

View on GitHub (pinned to fad1729dce)

Solutions

  1. Dereference the cause to find the exact converter failure
  2. Null-guard the converter and cover all domain values
  3. Verify the attribute is not being assigned values of the wrong type before flush
  4. Unit-test the converter with null plus every domain constant

Example fix

// before
@Override
public String convertToDatabaseColumn(ZonedDateTime v) {
    return v.format(DateTimeFormatter.ISO_ZONED_DATE_TIME); // NPE on null
}
// after
@Override
public String convertToDatabaseColumn(ZonedDateTime v) {
    return v == null ? null : v.format(DateTimeFormatter.ISO_ZONED_DATE_TIME);
}
Defensive patterns

Strategy: try-catch

Validate before calling

// validate before the unit of work that flushes
Object relational = entity.getValue() == null ? null : converter.convertToDatabaseColumn(entity.getValue());
// if the line above throws, fix data before persisting

Type guard

static <O, R> boolean safeToWrite(AttributeConverter<O, R> c, O value) {
    try { c.convertToDatabaseColumn(value); return true; }
    catch (RuntimeException e) { return false; }
}

Try / catch

try {
    tx.executeWithoutResult(s -> session.merge(entity));
} catch (PersistenceException e) {
    Throwable root = ExceptionUtils.getRootCause(e);
    if (root instanceof NullPointerException && entity.getWhen() == null) {
        entity.setWhen(Instant.now()); // nullable attribute hit an unguarded converter
        retry in a new transaction;
    } else throw e;
}

Prevention

When it happens

Trigger: INSERT/UPDATE of an entity whose converter's convertToDatabaseColumn throws - unhandled null domain value, unmapped enum constant, or an exception from formatting/parsing logic inside the converter.

Common situations: Null entity attribute reaching an unguarded converter; enum extended without updating the converter; locale-sensitive formatting failing in CI or another locale; bulk update statements pushing values through the converter.

Related errors


AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22). Data as JSON: /api/errors/0888b36155c0b2a5. Report an issue: GitHub.