{"record":{"id":"f8504033120f11d8","repo":"hibernate/hibernate-orm","slug":"the-property-s-s-uses-a-wrapper-type-byte-char","errorCode":null,"errorMessage":"The property %s.%s uses a wrapper type Byte[]/Character[] which indicates an issue in your domain model. These types have been treated like byte[]/char[] until Hibernate 6.2 which meant that null elements were not allowed, but on JDBC were processed like VARBINARY or VARCHAR. If you don't use nulls in your arrays, change the type of the property to byte[]/char[]. To allow explicit uses of the types Byte[]/Character[], allowing null elements, but with a different serialization format than before Hibernate 6.2, configure the setting '%s' to the value '%s'. To revert to the legacy treatment of these types, configure the value to '%s'. For more information on this matter, consult the migration guide of Hibernate 6.2 and the Javadoc of the field 'org.hibernate.cfg.AvailableSettings.WRAPPER_ARRAY_HANDLING'.","messagePattern":"The property %s\\.%s uses a wrapper type Byte\\[\\]/Character\\[\\] which indicates an issue in your domain model\\. These types have been treated like byte\\[\\]/char\\[\\] until Hibernate 6\\.2 which meant that null elements were not allowed, but on JDBC were processed like VARBINARY or VARCHAR\\. If you don't use nulls in your arrays, change the type of the property to byte\\[\\]/char\\[\\]\\. To allow explicit uses of the types Byte\\[\\]/Character\\[\\], allowing null elements, but with a different serialization format than before Hibernate 6\\.2, configure the setting '%s' to the value '%s'\\. To revert to the legacy treatment of these types, configure the value to '%s'\\. For more information on this matter, consult the migration guide of Hibernate 6\\.2 and the Javadoc of the field 'org\\.hibernate\\.cfg\\.AvailableSettings\\.WRAPPER_ARRAY_HANDLING'\\.","errorType":"exception","errorClass":"MappingException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/mapping/Property.java","lineNumber":321,"sourceCode":"\t\t\t|| BASIC.getExternalName().equals( propertyAccessorName );\n\t}\n\n\tpublic Map<String, MetaAttribute> getMetaAttributes() {\n\t\treturn metaAttributes;\n\t}\n\n\tpublic MetaAttribute getMetaAttribute(String attributeName) {\n\t\treturn metaAttributes==null ? null : metaAttributes.get(attributeName);\n\t}\n\n\tpublic void setMetaAttributes(Map<String, MetaAttribute> metas) {\n\t\tthis.metaAttributes = metas;\n\t}\n\n\tpublic boolean isValid(MappingContext mappingContext) throws MappingException {\n\t\tfinal Value value = getValue();\n\t\tif ( value instanceof BasicValue basicValue && basicValue.isDisallowedWrapperArray() ) {\n\t\t\tthrow new MappingException(\n\t\t\t\t\t\"\"\"\n\t\t\t\t\tThe property %s.%s uses a wrapper type Byte[]/Character[] which indicates an issue in your domain model. \\\n\t\t\t\t\tThese types have been treated like byte[]/char[] until Hibernate 6.2 which meant that null elements were \\\n\t\t\t\t\tnot allowed, but on JDBC were processed like VARBINARY or VARCHAR. If you don't use nulls in your arrays, \\\n\t\t\t\t\tchange the type of the property to byte[]/char[]. To allow explicit uses of the types Byte[]/Character[], \\\n\t\t\t\t\tallowing null elements, but with a different serialization format than before Hibernate 6.2, configure \\\n\t\t\t\t\tthe setting '%s' to the value '%s'. To revert to the legacy treatment of these types, configure the value to '%s'. \\\n\t\t\t\t\tFor more information on this matter, consult the migration guide of Hibernate 6.2 and the Javadoc of the \\\n\t\t\t\t\tfield 'org.hibernate.cfg.AvailableSettings.WRAPPER_ARRAY_HANDLING'.\\\n\t\t\t\t\t\"\"\"\n\t\t\t\t\t\t\t.formatted( persistentClass.getEntityName(), name, WRAPPER_ARRAY_HANDLING,\n\t\t\t\t\t\t\t\t\tWrapperArrayHandling.ALLOW, WrapperArrayHandling.LEGACY )\n\t\t\t);\n\t\t}\n\t\treturn value.isValid( mappingContext );\n\t}\n\n\tpublic String toString() {","sourceCodeStart":303,"sourceCodeEnd":339,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/mapping/Property.java#L303-L339","documentation":"Hibernate 6.2 changed how Byte[] and Character[] (wrapper arrays) are treated: before 6.2 they behaved like byte[]/char[] (no null elements, processed as VARBINARY/VARCHAR on JDBC); 6.2 gives them distinct semantics. When a property uses one of these types under the default handling, Property.isValid() throws this MappingException telling you to migrate to the primitive array or pick an explicit mode via the hibernate.type.wrapper_array_handling setting.","triggerScenarios":"An entity field of type Byte[] or Character[] (not byte[]/char[]) with no explicit wrapper-array handling configured; upgrading an application from Hibernate 6.1 or earlier to 6.2+; domain models that genuinely need nullable array elements.","commonSituations":"Hibernate 5.x/6.0/6.1 to 6.2+ upgrades; binary fields accidentally modeled with the boxed wrapper type; code generators emitting Byte[] for binary columns.","solutions":["If null elements are not needed, change the field type to byte[]/char[] (recommended)","If wrapper semantics are wanted, set hibernate.type.wrapper_array_handling=allow","To keep pre-6.2 behavior during migration, set hibernate.type.wrapper_array_handling=legacy","Consult the Hibernate 6.2 migration guide and the javadoc of AvailableSettings.WRAPPER_ARRAY_HANDLING"],"exampleFix":"// before\n@Entity class Document { @Column(name = \"payload\") Byte[] payload; }\n\n// after\n@Entity class Document { @Column(name = \"payload\") byte[] payload; }\n// or keep Byte[] and configure: hibernate.type.wrapper_array_handling=allow","handlingStrategy":"validation","validationCode":"// scan entities for wrapper-array fields before upgrading or booting on 6.2+\nstatic List<String> wrapperArrayFields(Class<?>... entities) {\n    List<String> hits = new ArrayList<>();\n    for (Class<?> e : entities)\n        for (Field f : e.getDeclaredFields())\n            if (f.getType() == Byte[].class || f.getType() == Character[].class)\n                hits.add(e.getSimpleName() + '.' + f.getName());\n    return hits; // empty means this change cannot bite you\n}","typeGuard":"static boolean isWrapperArrayField(Field f) {\n    return f.getType() == Byte[].class || f.getType() == Character[].class;\n}","tryCatchPattern":null,"preventionTips":["Model binary data as byte[], never Byte[]","Set hibernate.type.wrapper_array_handling explicitly (allow or legacy) before upgrading to 6.2+","Run the wrapper-array scan in CI when planning a Hibernate upgrade"],"tags":["hibernate","orm","migration","hibernate-6-2","type-mapping","wrapper-array"],"backgroundTag":"hibernate-6-migration","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}