hibernate/hibernate-orm · error · IllegalArgumentException
Could not find selectable [%s] in embeddable type [%s] for X
Error message
Could not find selectable [%s] in embeddable type [%s] for XML processing.
What it means
During XML aggregate parsing, Hibernate looked up an element name from the stored data among the embeddable's selectables and found no match. The parser resolves tags by selectable (attribute) name, so any element unknown to the current mapping fails with 'Could not find selectable'.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/type/descriptor/jdbc/XmlHelper.java:963
appender.append( START_TAG );
convertedBasicValueToString( appender, arrayElement, options, elementJavaType, elementJdbcType );
appender.append( END_TAG );
}
}
}
}
break;
default:
throw new UnsupportedOperationException( "Unsupported JdbcType nested in struct: " + jdbcType );
}
}
private static int getSelectableMapping(
EmbeddableMappingType embeddableMappingType,
String name) {
final int selectableIndex = embeddableMappingType.getSelectableIndex( name );
if ( selectableIndex == -1 ) {
throw new IllegalArgumentException(
String.format(
"Could not find selectable [%s] in embeddable type [%s] for XML processing.",
name,
embeddableMappingType.getMappedJavaType().getJavaTypeClass().getName()
)
);
}
return selectableIndex;
}
public static boolean isValidXmlName(String name) {
if ( name.isEmpty()
|| !isValidXmlNameStart( name.charAt( 0 ) )
|| name.regionMatches( true, 0, "xml", 0, 3 ) ) {
return false;
}
for ( int i = 1; i < name.length(); i++ ) {
if ( !isValidXmlNameChar( name.charAt( i ) ) ) {View on GitHub (pinned to fad1729dce)
Solutions
- Keep attribute names stable, or migrate stored element names together with the rename.
- Remove stray elements from stored rows so data matches the deployed mapping.
- If tags are explicit (e.g. @Struct/@Column names), make them match the stored tags exactly.
Example fix
-- PostgreSQL: rename element tags together with the field rename -- code: String postCode -> String zipCode UPDATE t SET xml_col = REPLACE(xml_col, '<postCode>', '<zipCode>'); UPDATE t SET xml_col = REPLACE(xml_col, '</postCode>', '</zipCode>');
Defensive patterns
Strategy: validation
Validate before calling
static void assertTagsMatchMapping(Class<?> embeddable, Set<String> storedTags) {
Set<String> fields = Arrays.stream(embeddable.getDeclaredFields())
.map(Field::getName).collect(Collectors.toSet());
for (String tag : storedTags) {
if (!fields.contains(tag)) {
throw new IllegalStateException(
"Stored XML element <" + tag + "> has no field in " + embeddable.getName());
}
}
} Try / catch
try {
return session.find(Person.class, id);
} catch (IllegalArgumentException ex) {
if (ex.getMessage() != null && ex.getMessage().contains("Could not find selectable")) {
quarantine(id, ex.getMessage()); // row layout does not match deployed mapping
return null;
}
throw ex;
} Prevention
- Pair every embeddable field rename with a data migration updating stored tags.
- Keep explicit, stable column/tag names on aggregate fields.
- Compare stored element names with the mapping during staging deployments.
When it happens
Trigger: Loading an XML aggregate where stored rows contain element names that no longer (or do not yet) exist in the embeddable: a field was renamed without migrating data, extra elements were added by another writer, or the column was written by a different application version.
Common situations: Renaming embeddable attributes across releases; sharing one column between services with different models; restored backups paired with newer code.
Related errors
- XML starts sub-object for a non-aggregate type at index %d.
- Illegal XML content:
- XML not properly formatted:
- XML not properly formed:
- Support for attribute mapping type not yet implemented:
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/29b607c85fa8b754.
Report an issue: GitHub.