hibernate/hibernate-orm · error · MappingException

Class<?> '%s' declares both 'get' [%s] and 'is' [%s] variant

Error message

Class<?> '%s' declares both 'get' [%s] and 'is' [%s] variants of getter for property '%s'

What it means

When resolving a property, Hibernate can discover both a getFoo() and an isFoo() variant. ReflectHelper.checkGetAndIsVariants accepts the pair only when both methods declare exactly the same return type; otherwise it throws MappingException because there is no way to decide which accessor defines the property's type. Boolean and primitive boolean are different Class objects, so a wrapper/primitive mix between the two forms is enough to fail.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/internal/util/ReflectHelper.java:581

				// No such method should throw the caught exception.  So if we get here, there was
				// such a method.
				checkGetAndIsVariants( containerClass, propertyName, getMethod, isMethod );
			}
		}
		catch (NoSuchMethodException ignore) {
		}
	}


	public static void checkGetAndIsVariants(
			Class<?> containerClass,
			String propertyName,
			Method getMethod,
			Method isMethod) {
		// Check the return types.  If they are the same, its ok.  If they are different
		// we are in a situation where we could not reasonably know which to use.
		if ( !isMethod.getReturnType().equals( getMethod.getReturnType() ) ) {
			throw new MappingException(
					String.format(
							Locale.ROOT,
							"Class<?> '%s' declares both 'get' [%s] and 'is' [%s] variants of getter for property '%s'",
							containerClass.getName(),
							getMethod,
							isMethod,
							propertyName
					)
			);
		}
	}

	public static void verifyNoGetVariantExists(
			Class<?> containerClass,
			String propertyName,
			Method isMethod,
			String stemName) {
		// verify that the Class<?> does not also define a method with the same stem name with 'is'

View on GitHub (pinned to fad1729dce)

Solutions

  1. Delete one of the two accessors so a single getter form remains for the property.
  2. Make both return types identical (both Boolean or both boolean).
  3. Rename one accessor so it is no longer the same JavaBean property and, on mapped classes, exclude it with @Transient.

Example fix

// before
public class Task {
    public Boolean getDone() { return done; } // wrapper
    public boolean isDone() { return done; }  // primitive -> MappingException
}

// after
public class Task {
    public boolean isDone() { return done; }
}
Defensive patterns

Strategy: validation

Validate before calling

static List<String> findConflictingGetAndIsVariants(Class<?> clazz) {
    java.util.List<String> conflicts = new java.util.ArrayList<>();
    for (var is : clazz.getMethods()) {
        String n = is.getName();
        if (!n.startsWith("is") || n.length() <= 2 || is.getParameterCount() != 0) continue;
        String getterName = "get" + Character.toUpperCase(n.charAt(2)) + n.substring(3);
        for (var get : clazz.getMethods()) {
            if (get.getName().equals(getterName) && get.getParameterCount() == 0
                    && !get.getReturnType().equals(is.getReturnType())) {
                conflicts.add(getterName + "/" + n);
            }
        }
    }
    return conflicts;
}

Try / catch

try {
    SessionFactory sf = metadata.buildSessionFactory();
} catch (org.hibernate.MappingException e) {
    // message lists both method signatures; delete one accessor or unify the return types
}

Prevention

When it happens

Trigger: A mapped class (or a class inspected via ReflectHelper.getGetter) declares both getX() and isX() with different return types, e.g. Boolean getDone() plus boolean isDone(), or int getReady() plus boolean isReady(). The check runs while property accessors are built during metadata/SessionFactory creation.

Common situations: Accessors written at different times by different tools (IDE generation plus a later hand-written is-getter); wrapper Boolean on one accessor and primitive boolean on the other; copy-pasted DTOs promoted to @Embeddable; Lombok-generated getter plus a manually added is-getter.

Related errors


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