Los objetos de dominio como identificadores crean algunos problemas complejos / sutiles:
Serialización / Deserialización
Si almacena objetos como claves, la serialización del gráfico de objetos será extremadamente complicada. Obtendrá stackoverflowerrores cuando realice una serialización ingenua a JSON o XML debido a la recursividad. Luego tendrá que escribir un serializador personalizado que convierta los objetos reales para usar sus identificadores en lugar de serializar la instancia del objeto y crear la recursividad.
Pase objetos por seguridad de tipo pero solo almacene identificadores, luego puede tener un método de acceso que perezosamente carga la entidad relacionada cuando se llama. El almacenamiento en caché de segundo nivel atenderá las llamadas posteriores.
Fugas de referencia sutiles:
Si usa objetos de dominio en constructores como los que tiene allí, creará referencias circulares que serán muy difíciles de permitir que se recupere la memoria para objetos que no se usan activamente.
Situación ideal:
ID opacos vs int / long:
Un iddebe ser un identificador completamente opaco que no contenga información sobre lo que identifica. Pero debería ofrecer alguna verificación de que es un identificador válido en su sistema.
Los tipos sin procesar rompen esto:
int, longyString son los tipos sin formato más utilizados para identificadores en el sistema RDBMS. Hay una larga historia de razones prácticas que se remontan a décadas y todas son compromisos que encajan en el ahorro spaceo el ahorro timeo en ambos.
Los identificadores secuenciales son los peores delincuentes:
Cuando utiliza una identificación secuencial, está empaquetando información semántica temporal en la identificación de forma predeterminada. Que no esta mal hasta que se usa. Cuando las personas comienzan a escribir una lógica comercial que clasifica o filtra la calidad semántica de la identificación, están creando un mundo de dolor para los futuros mantenedores.
String los campos son problemáticos porque los diseñadores ingenuos empaquetarán información en los contenidos, generalmente también la semántica temporal.
Esto hace que sea imposible crear un sistema de datos distribuidos también, porque no12437379123 es único a nivel mundial. Las posibilidades de que otro nodo en un sistema distribuido cree un registro con el mismo número está prácticamente garantizado cuando obtiene suficientes datos en un sistema.
Luego, los hacks comienzan a solucionarlo y todo se convierte en un montón de vapor.
Ignorando los grandes sistemas distribuidos ( clusters ), se convierte en una pesadilla completa cuando comienza a tratar de compartir los datos con otros sistemas también. Especialmente cuando el otro sistema no está bajo su control.
Termina con exactamente el mismo problema, cómo hacer que su identificación sea globalmente única.
UUID fue creado y estandarizado por una razón:
UUIDpuede sufrir todos los problemas enumerados anteriormente dependiendo de cuál Versionuse.
Version 1usa una dirección MAC y tiempo para crear una identificación única. Esto es malo porque lleva información semántica sobre la ubicación y la hora. Eso no es en sí un problema, es cuando los desarrolladores ingenuos comienzan a confiar en esa información para la lógica empresarial. Esto también filtra información que podría ser explotada en cualquier intento de intrusión.
Version 2el uso de un usuario UIDo un GIDdomian UIDo GUIen lugar del tiempo a partir de Version 1esto es tan malo como Version 1para la fuga de datos y el riesgo de que esta información se use en la lógica empresarial.
Version 3es similar pero reemplaza la dirección MAC y el tiempo con un MD5hash de una serie de byte[]algo que definitivamente tiene un significado semántico. No hay pérdida de datos de la que preocuparse, byte[]no se puede recuperar del UUID. Esto le brinda una buena forma de crear de UUIDforma determinista instancias de forma y clave externa de algún tipo.
Version 4 se basa solo en números aleatorios, lo cual es una buena solución, no contiene absolutamente ninguna información semántica, pero no es reproducible determinísticamente.
Version 5es igual Version 4pero usa en sha1lugar demd5 .
Claves de dominio y claves de datos transaccionales
Mi preferencia por los identificadores de objeto de dominio es usar Version 5o, Version 3si está restringido, Version 5por alguna razón técnica.
Version 3 es excelente para los datos de transacciones que pueden distribuirse en muchas máquinas
A menos que esté limitado por el espacio, use un UUID:
Están garantizados como únicos, volcando datos de una base de datos y volviendo a cargarlos en otra, nunca tuvo que preocuparse por identificadores duplicados que realmente hacen referencia a diferentes datos de dominio.
Version 3,4,5 son completamente opacos y así es como deberían ser.
Puede tener una sola columna como clave principal con ay UUIDluego puede tener índices únicos compuestos para lo que habría sido una clave primaria compuesta natural.
El almacenamiento no tiene que ser CHAR(36)tampoco. Puede almacenarlo UUIDen un campo byte / bit / número nativo para una base de datos determinada siempre que sea indexable.
Legado
Si tiene tipos sin procesar y no puede cambiarlos, aún puede abstraerlos en su código.
El uso de uno Version 3/5de UUIDustedes puede pasar el Class.getName()+ String.valueOf(int)como a byte[]y tener una clave de referencia opaca que sea recreable y determinista.