hibernate/hibernate-orm · error · CoercionException

Unable to convert string [%s] to URL : %s

Error message

Unable to convert string [%s] to URL : %s

What it means

UrlJavaType is the basic type descriptor for java.net.URL attributes. Whenever a URL must be rebuilt from its string form (row load, query-parameter coercion, AttributeConverter input), it calls new URL(String) and wraps any MalformedURLException in a CoercionException. The message shows both the offending string and the underlying JDK parse reason.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/type/descriptor/java/UrlJavaType.java:56

	public JdbcType getRecommendedJdbcType(JdbcTypeIndicators context) {
		return context.getJdbcType( SqlTypes.VARCHAR );
	}

	@Override
	public boolean useObjectEqualsHashCode() {
		return true;
	}

	public String toString(URL value) {
		return value.toExternalForm();
	}

	public URL fromString(CharSequence string) {
		try {
			return new URL( string.toString() );
		}
		catch ( MalformedURLException e ) {
			throw new CoercionException( "Unable to convert string [" + string + "] to URL : " + e );
		}
	}

	public <X> X unwrap(URL value, Class<X> type, WrapperOptions options) {
		if ( value == null ) {
			return null;
		}
		if ( URL.class.isAssignableFrom( type ) ) {
			return type.cast( value );
		}
		if ( String.class.isAssignableFrom( type ) ) {
			return type.cast( toString( value ) );
		}
		throw unknownUnwrap( type );
	}

	public <X> URL wrap(X value, WrapperOptions options) {
		if ( value == null ) {

View on GitHub (pinned to fad1729dce)

Solutions

  1. Fix the stored data: every row must contain an absolute, well-formed URL including protocol and host
  2. Map the column as String or java.net.URI instead — URI tolerates relative references that URL rejects
  3. Add an AttributeConverter that normalizes values (e.g. prefixes 'http://') before new URL() runs
  4. Validate URLs at write time so malformed values never reach the database

Example fix

// before
@Entity class Link {
    @Column(name = "target") URL target; // column holds '/docs/page' -> throws on load
}

// after
@Entity class Link {
    @Column(name = "target") String target; // or java.net.URI, which parses relative refs
}
Defensive patterns

Strategy: try-catch

Validate before calling

static boolean isAbsoluteUrl(String s) {
    if (s == null || s.isBlank()) return false;
    try { new java.net.URL(s); return true; }
    catch (java.net.MalformedURLException e) { return false; }
}

Try / catch

try {
    Link link = session.find(Link.class, id);
} catch (org.hibernate.type.descriptor.java.CoercionException e) {
    java.net.MalformedURLException cause = (java.net.MalformedURLException) e.getCause();
    // route to data-repair path (skip row, queue for cleanup) instead of failing the whole load
}

Prevention

When it happens

Trigger: Loading an entity whose java.net.URL column contains a non-URL string; binding a String parameter into a URL-typed attribute; criteria/coercion calls that convert arbitrary strings to URL; importing rows where the column holds relative paths or placeholder text.

Common situations: Relative URLs like '/docs/page' (no protocol) stored in the column; migrated or user-submitted data containing 'N/A', empty strings or strings with unencoded spaces; switching an attribute from String to URL without cleansing existing rows.

Related errors


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