HibernateMapper.javaMapperWrapper (Decorator pattern) to serve as the central mapper for all Hibernate-aware XStream serialization. It performs two critical functions: (1) substituting Hibernate's internal collection implementation classes with their standard JDK equivalents when determining default implementations during marshalling/unmarshalling, and (2) detecting HibernateProxy instances by checking implemented interfaces and resolving their real superclass names for XML element naming. This is the most comprehensive of the Hibernate XStream components — it handles PersistentBag (which the older HibernateCollectionsMapper omits) and also detects HibernateProxy wrappers that HibernateCollectionsMapper ignores.HibernateMapper extends com.thoughtworks.xstream.mapper.MapperWrapper, the base class for XStream mapper decorators. Two constructors accept either MapperWrapper or plain Mapper delegates and call init() to populate the collection substitution map.
The init() method populates a Map<Class<?>, Class<?>> with six Hibernate→JDK mappings:
| Hibernate Persistent Collection | JDK Replacement |
|---|---|
PersistentBag | ArrayList |
PersistentList | ArrayList |
PersistentMap | HashMap |
PersistentSet | HashSet |
PersistentSortedMap | TreeMap |
PersistentSortedSet | TreeSet |
PersistentBag — the default Hibernate collection for un-indexed List fields declared without @OrderColumn. This is the most common collection type in ProjectForge entities and its absence from the older mapper is a notable gap.Called by XStream when it needs to instantiate a concrete class for an interface or abstract type (e.g., when deserializing a List field, XStream asks what implementation to create). If the requested class is in the collectionMap, the JDK replacement is returned. This ensures deserialized XML produces plain ArrayList/HashSet objects rather than Hibernate-specific implementations that would be broken without a Hibernate session.
Called by XStream to determine the class name to write into the XML. This method performs a two-step check:
clazz.getInterfaces() looking for HibernateProxy.class. If found, returns clazz.getSuperclass().getName() — the real entity class name. This ensures <org.projectforge.business.user.UserDO> appears in XML rather than <org.projectforge.business.user.UserDO_$$_jvstXXX> (the Javassist-generated proxy name).collectionMap, returns the JDK replacement's fully-qualified name.super.serializedClass(clazz).XStream initialization.HibernateMapper and HibernateCollectionsMapper (#703) should not both be active simultaneously — they would double-substitute and cause issues. HibernateMapper is the preferred, more complete implementation.getInterfaces() to find HibernateProxy is somewhat fragile — it assumes the Javassist/CGLIB proxy implements HibernateProxy as one of its interfaces. In modern Hibernate 5.x, this is reliable, but alternative proxy frameworks (like Spring's @Transactional proxies) may not implement this interface. The code has commented-out System.err.println debug lines suggesting this was iteratively debugged.clazz.getSuperclass().getName() works because Hibernate proxies are generated as subclasses of the entity class (e.g., UserDO_$$_jvstXXX extends UserDO). This is correct for the class name but doesn't handle the case where the proxy chain is deeper (CGLIB nested proxies).HashMap for collectionMap is cleaner and more maintainable than the parallel arrays in HibernateCollectionsMapper. Adding new mappings is a one-line change to init().MapperWrapper and plain Mapper suggest this class was evolved over time and needs to integrate at different points in the mapper decorator chain.868d6abb7 2025 -> 2026 63081666f Source file headers: 2024-> 2025. c1d14ecdb Migration stuff in progress... b6092df09 Copyright 2023 -> 2024 ab45d51fa Copyright 2001-2022 -> 2001-2023. 5f7ef41b8 Copyright 2021 -> 2022 ceb63e8a1 Source code header: (C) 2001-2021. 7c79f1922 Copyright of source header -> 2020. 73a9755df More code cleanup 32f634b88 Optimize imports dd5ca38ac CopyRight of all java file-header updated or created. 9ebb88522 Initial commit