code: public <T> JaversBuilder registerValueWithCustomToString(Class<T> valueClass, Function<T, String> toString) {
          argumentsAreNotNull(valueClass, toString);
  
          if (!clientsClassDefinitions.containsKey(valueClass)){
              registerType(new ValueDefinition(valueClass));
          }
          ValueDefinition def = getClassDefinition(valueClass);
          def.setToStringFunction((Function)toString);
  
          return this;
      }
docs: For complex <code>ValueType</code> classes that are used as Entity Id.
  <br/><br/>
  
  Registers a custom <code>toString</code> function that will be used for creating
  <code>GlobalId</code> for Entities,
  instead of default {@link ReflectionUtil#reflectiveToString(Object)}.
  <br/><br/>
  
  For example:
  
  <pre>
  class Entity {
  &#64;Id Point id
  String data
  }
  
  class Point {
  double x
  double y
  
  String myToString() {
  "("+ (int)x +"," +(int)y + ")"
  }
  }
  
  def "should use custom toString function for complex Id"(){
  given:
  Entity entity = new Entity(
  id: new Point(x: 1/3, y: 4/3))
  
  when: "default reflectiveToString function"
  def javers = JaversBuilder.javers().build()
  GlobalId id = javers.getTypeMapping(Entity).createIdFromInstance(entity)
  
  then:
  id.value() == "com.mypackage.Entity/0.3333333333,1.3333333333"
  
  when: "custom toString function"
  javers = JaversBuilder.javers()
  .registerValueWithCustomToString(Point, {it.myToString()}).build()
  id = javers.getTypeMapping(Entity).createIdFromInstance(entity)
  
  then:
  id.value() == "com.mypackage.Entity/(0,1)"
  }
  </pre>
  
  For <code>ValueType</code> you can register both
  custom <code>toString</code> function and <code>CustomValueComparator</code>.
  
  @param toString should return String value of a given object
  @see ValueType
  @see #registerValue(Class, CustomValueComparator)
  @since 3.7.6