diff --git a/GaudiKernel/include/GaudiKernel/DataObjID.h b/GaudiKernel/include/GaudiKernel/DataObjID.h
index f37c39e767aa1f77ea024cf52e0c5cb5204de4e5..eb6b78205273fa60ed3f5da9ca21ac0f9979cf3f 100644
--- a/GaudiKernel/include/GaudiKernel/DataObjID.h
+++ b/GaudiKernel/include/GaudiKernel/DataObjID.h
@@ -1,5 +1,5 @@
 /***********************************************************************************\
-* (c) Copyright 1998-2024 CERN for the benefit of the LHCb and ATLAS collaborations *
+* (c) Copyright 1998-2025 CERN for the benefit of the LHCb and ATLAS collaborations *
 *                                                                                   *
 * This software is distributed under the terms of the Apache version 2 licence,     *
 * copied verbatim in the file "LICENSE".                                            *
@@ -15,6 +15,7 @@
 #include <GaudiKernel/StatusCode.h>
 
 #include <iostream>
+#include <memory>
 #include <mutex>
 #include <string>
 #include <unordered_set>
@@ -48,19 +49,27 @@ class DataObjID {
 public:
   friend DataObjID_Hasher;
 
-  DataObjID()                   = default;
-  DataObjID( const DataObjID& ) = default;
+  DataObjID() = default;
+  DataObjID( const DataObjID& other )
+      : m_clid( other.m_clid ), m_hash( other.m_hash ), m_key( other.m_key ), m_className( other.m_className ) {}
+
   DataObjID( std::string key );
   DataObjID( const CLID& clid, std::string key );
   DataObjID( std::string className, std::string key );
 
-  DataObjID& operator=( const DataObjID& ) = default;
+  DataObjID& operator=( const DataObjID& other ) {
+    m_clid      = other.m_clid;
+    m_hash      = other.m_hash;
+    m_key       = other.m_key;
+    m_className = other.m_className;
+    return *this;
+  }
 
   /// only return the last part of the key
   const std::string& key() const { return m_key; }
 
   /// return the ClassName (if available)
-  const std::string& className() const { return m_className; }
+  const std::string& className() const;
 
   /// combination of the key and the ClassName, mostly for debugging
   std::string fullKey() const;
@@ -81,22 +90,18 @@ public:
 private:
   void hashGen();
   void setClid();
-  void setClassName();
 
   CLID        m_clid{ 0 };
   std::size_t m_hash{ 0 };
 
-  std::string m_key{ "INVALID" };
-  std::string m_className;
-
-  static IClassIDSvc*   p_clidSvc;
-  static std::once_flag m_ip;
+  std::string            m_key{ "INVALID" };
+  mutable std::string    m_className;
+  mutable std::once_flag m_setClassName;
 };
 
 inline DataObjID::DataObjID( std::string key ) : m_key( std::move( key ) ) { hashGen(); }
 
 inline DataObjID::DataObjID( const CLID& clid, std::string key ) : m_clid( clid ), m_key( std::move( key ) ) {
-  setClassName();
   hashGen();
 }
 
diff --git a/GaudiKernel/src/Lib/DataObjID.cpp b/GaudiKernel/src/Lib/DataObjID.cpp
index 8c8189c559c1d6ffe74a7916a834e48687774470..7b1582c2a657c85c09dcbad1fbf120be952a3b40 100644
--- a/GaudiKernel/src/Lib/DataObjID.cpp
+++ b/GaudiKernel/src/Lib/DataObjID.cpp
@@ -1,5 +1,5 @@
 /***********************************************************************************\
-* (c) Copyright 1998-2024 CERN for the benefit of the LHCb and ATLAS collaborations *
+* (c) Copyright 1998-2025 CERN for the benefit of the LHCb and ATLAS collaborations *
 *                                                                                   *
 * This software is distributed under the terms of the Apache version 2 licence,     *
 * copied verbatim in the file "LICENSE".                                            *
@@ -13,6 +13,7 @@
 #include <GaudiKernel/DataObjID.h>
 #include <GaudiKernel/IClassIDSvc.h>
 #include <GaudiKernel/ISvcLocator.h>
+#include <GaudiKernel/ToStream.h>
 #include <functional>
 #include <iomanip>
 #include <iostream>
@@ -56,31 +57,22 @@ namespace Gaudi {
 
 StatusCode parse( DataObjID& dest, std::string_view src ) { return Gaudi::Parsers::parse_( dest, quote( src ) ); }
 
-IClassIDSvc*   DataObjID::p_clidSvc( nullptr );
-std::once_flag DataObjID::m_ip;
 namespace {
-  auto getClidSvc = []( std::reference_wrapper<IClassIDSvc*> p ) {
-    p.get() = Gaudi::svcLocator()->service<IClassIDSvc>( "ClassIDSvc" ).get();
+  /// Helper to retrieve and cache pointer to ClassIDSvc if available
+  IClassIDSvc* getClidSvc() {
+    static IClassIDSvc* clidSvc = Gaudi::svcLocator()->service<IClassIDSvc>( "ClassIDSvc" ).get();
+    return clidSvc;
   };
-}
+} // namespace
 
 void DataObjID::setClid() {
-  std::call_once( m_ip, getClidSvc, std::ref( p_clidSvc ) );
 
-  if ( !p_clidSvc || p_clidSvc->getIDOfTypeName( m_className, m_clid ).isFailure() ) {
+  if ( !getClidSvc() || getClidSvc()->getIDOfTypeName( m_className, m_clid ).isFailure() ) {
     m_clid      = 0;
     m_className = "UNKNOWN_CLASS:" + m_className;
   }
 }
 
-void DataObjID::setClassName() {
-  std::call_once( m_ip, getClidSvc, std::ref( p_clidSvc ) );
-
-  if ( !p_clidSvc || p_clidSvc->getTypeNameOfID( m_clid, m_className ).isFailure() ) {
-    m_className = "UNKNOW_CLID:" + std::to_string( m_clid );
-  }
-}
-
 void DataObjID::hashGen() {
   m_hash = ( std::hash<std::string>()( m_key ) );
   if ( m_clid != 0 ) {
@@ -89,15 +81,27 @@ void DataObjID::hashGen() {
   }
 }
 
-#include <GaudiKernel/ToStream.h>
 std::ostream& toStream( const DataObjID& d, std::ostream& os ) {
   using Gaudi::Utils::toStream;
-  return ( d.m_clid != 0 || !d.m_className.empty() ) ? toStream( std::tie( d.m_className, d.m_key ), os )
+  return ( d.m_clid != 0 || !d.className().empty() ) ? toStream( std::tie( d.className(), d.m_key ), os )
                                                      : toStream( d.m_key, os );
 }
 
+const std::string& DataObjID::className() const {
+
+  // Set class name once if not done already
+  if ( m_clid !=0 && m_className.empty() ) {
+    std::call_once( m_setClassName, [&]() {
+      if ( !getClidSvc() || getClidSvc()->getTypeNameOfID( m_clid, m_className ).isFailure() ) {
+        m_className = "UNKNOWN_CLID:" + std::to_string( m_clid );
+      }
+    } );
+  }
+  return m_className;
+}
+
 std::string DataObjID::fullKey() const {
-  return ( m_clid == 0 && m_className.empty() ) ? m_key : ( m_className + '/' + m_key );
+  return ( m_clid == 0 && m_className.empty() ) ? m_key : ( className() + '/' + m_key );
 }
 
 std::string Gaudi::Details::Property::StringConverter<DataObjIDColl>::toString( const DataObjIDColl& v ) {