Sí, puede implementar el patrón Flyweight con Hibernate.
El patrón flyweight es una forma de minimizar el uso de la memoria por instancia. La estrategia es compartir tanto estado como sea posible entre las instancias flyweight. En su caso, el estado compartible es todo excepto el identificador de objeto de hibernación y algún estado adicional para mantener la identidad del objeto.
Cada instancia de flyweight necesita su propia object identity. El estado adicional es la forma de implementar identidad para distinguir entre objetos que comparten estado común.
public boolean equals(Object obj){
Fly other; [..]//check type
//null checks ommitted
return other.myState.equals(myState) && other.commonState.equals(commonState);
}
Si la identidad del objeto es compartida entre instancias de hibernación interpretaría todas las instancias físicas (Referencias) como la misma instancia. Hibernate usa el método equals para verificar la identidad del objeto y su implementación equitativa debería devolver (! a.equals(a) == true)
que es ilegal. Equal tiene que ser reflexivo. Si rompe este contrato, todas las bibliotecas que dependen del contrato se romperán (colecciones, hibernación, etc.).
No se puede implementar el método igual utilizando el identificador de objeto de hibernación para distinguir entre objetos. Esto haría que la identidad del objeto dependiera del estado de persistencia (persistente o transitorio).
Una forma de modelar el estado común en hibernación es una asociación uno a muchos entre objetos de estado compartido y objetos flyweight. (Tal vez alguien tiene una idea de cómo mapear los datos sin unir dos tablas?)
Cadena: Solo internalized strings serán compartidos. Esta no es la mejor solución la mayor parte del tiempo. Es apropiado para símbolos (nombre de clase, nombre del método, etc.). Las cadenas internalizadas nunca se recolectarán por basura y debe tener una instancia de String que se recolectará de todos modos new String("..").intern()
. No guardará las asignaciones. Solo existe la pequeña ventaja de que la cadena base no sobrevivirá a una generación de gc o podría asignarse en la pila (con el análisis de escape habilitado y aplicable en la zona activa).
El tipo de usuario es una buena idea para mapear el estado común de las instancias flyweight. (Hibernate y JDBC todavía iniciarán una gran cantidad de instancias. No hay forma de evitarlo. Al menos serán recolección de basura con bastante rapidez). ¿Podría un CompositeUserType representar el estado común completo en un objeto? –
Sí, un tipo de usuario compuesto probablemente podría hacer eso, pero ¿por qué tener la entidad como entidad en primer lugar? Solo tiene que ser un objeto de valor (componente) desde el principio. –