Estoy bastante seguro de que finalizar sigue siendo una mala noticia para las JVM posteriores. ¿Existe alguna alternativa?

StackOverflow https://stackoverflow.com/questions/5359367

  •  27-10-2019
  •  | 
  •  

Pregunta

Me gustaría implementar un sistema de estilo ORM que pueda guardar actualizaciones de los POJO cuando la persona que llama ya no puede acceder a ellos.

Pensé que las clases de referencia podrían hacerlo, pero parece que solo ponen en cola la referencia después de que se ha borrado el objeto (esperaba que fuera cuando pudieran recopilarse), por lo que una vez puesto en cola, el método .get() siempre regresará nulo.

Podría usar un finalizador, pero la última vez que lo verifiqué eran cuestionables (no se garantiza que se ejecuten rápidamente o que se ejecuten en absoluto). Creo que una combinación de finalizadores y runShutdownHook() funcionaría, pero eso se está adentrando en un territorio bastante pantanoso.

¿Hay otra ruta en la que no estoy pensando además del obligatorio "Simplemente haga que la persona que llama llame a .save() cuando haya terminado"?

¿Fue útil?

Solución

¿Estás tratando de evitar tener que llamar? save() ¿En cada pojo que modifiques?

Esto se puede hacer de manera confiable utilizando un objeto de sesión de persistencia, como este:

  1. Abra un nuevo objeto de sesión.
  2. Cargue objetos a través del objeto de sesión. El objeto de sesión mantiene las referencias a todos los objetos que carga.
  3. Hacer cualquier cambio en los objetos cargados. No es necesario llamar a un método de guardado en objetos actualizados.
  4. Cierre el objeto de sesión. La sesión guarda todos sus objetos. Incluso puede ser lo suficientemente elegante como para mantener una copia de los datos cargados limpios, comparar todos sus objetos con los datos limpios y guardar solo los que se han modificado.

Y si no desea pasar objetos de sesión a través de su código, puede llevar las cosas un paso más allá con el patrón de la unidad de trabajo, asociando un objeto de sesión al hilo actual:

  1. Iniciar una unidad de trabajo. Esto crea un objeto de sesión detrás de escena y lo asocia con el hilo actual.
  2. Cargar objetos. Cada vez que se carga un objeto, su ORM lo asocia automáticamente con un objeto de sesión basado en el hilo actual.
  3. Hacer cualquier cambio en los objetos cargados. No es necesario llamar a un método de guardado en objetos actualizados.
  4. Completa la unidad de trabajo. Esto cierra el objeto de sesión, guardando todos los objetos.

Esto soluciona varios problemas con una solución basada en accesibilidad:

  • No confía en las colecciones de basura no deterministas, que pueden tener mucho tiempo entre carreras, o no correr en absoluto.
  • Todos los objetos modificados en una operación se guardan juntos. Si confía en la accesibilidad, los diferentes objetos modificados en la misma operación pueden volverse inalcanzables en diferentes momentos, lo que significa que sus modificaciones se pueden guardar en la base de datos en bits y piezas.
  • La reversión es mucho más fácil: solo dé a su objeto de sesión un método Rollback (). Con una solución de accesibilidad, deberá recordar llamar a Rollback () en cada POJO modificado si una operación falla, que es realmente lo mismo que su problema original.

Quizás ver http://nhibernate.info/doc/patternsandpractices/nhibernate-and-the-unit-of-work-pattern.html o investigar la unidad de patrón de trabajo y emular algunas de esas ideas.

Otros consejos

Use el patrón Observador que construya un ClearANCEMAGER y algunos destruibles. IdestrOyable es una interfaz, que se utiliza para los observadores que contiene el método público nula destruye () El clearancemanager es el tema del observador. Tal vez use Singleton aquí para asegurarse de tener solo un objeto Clearancemanager en su aplicación.

Use un conjunto internal dentro del ClearANCEMAGER (no una lista para asegurarse de que los objetos se puedan agregar una vez)

Admite un método addestrOyable (idestroyable Destoryable) (y tal vez uno eliminable).

Durante el tiempo de ejecución, las clases para las que necesitas algo de emulación de destructor, pueden registrarlas en el ClearEndemanager. ClearEnCemanager.getInStance (). AddDestrOyable (esto);

El ClearancManager tiene un método DoClearance (), que debería llamarse al final del método principal. Iterate lanzó el conjunto privado y llamó a Destro () en cada objeto idealtable.

Hacerlo de esta manera puede emular destructores, sin usarlos, porque usando destructores está perdiendo el control sobre la existencia del objeto necesario de Myabe. No sabes al finalizar la sobrescribencia, cuando se llama.

Tal vez, si no desea llamar a DoClearance () en su método principal que puede usar aquí, pero solo aquí, un verdadero destructor finalize (). Debido a que hay referencias en el ClearenManager a los objetos necesarios, no serán destruidos primero. Pero tal vez MHH, si hay referencias cruzadas ... es mejor que no use finalizar, use doClearance () y diviértete con él :)

Creo que estás ladrando al árbol equivocado.

Todos los mecanismos finalizadores y de referencia de Java basados ​​en la accesibilidad dependen del recolector de basura para determinar si los objetos respectivos son accesibles.Entonces, si utiliza cualquiera de los mecanismos de referencia para algún tipo de finalización, se encontrará con los mismos problemas que hacen que finalize una mala idea.

Es técnicamente posible implementar sus propios mecanismos para lograr la accesibilidad;p.ej.implementando su propio recuento de referencias específico de la aplicación.Sin embargo, es probable que sea costoso, frágil y haga que su código se vea horrible.(Es probable que el recuento de referencias en Java sea más complicado y frágil que en C++, porque no se pueden sobrecargar los operadores de asignación de referencias para garantizar que los recuentos de referencias se ajusten de forma transparente.Por lo tanto, cada asignación de referencia debe incluirse en una llamada a un método). Entonces, yo diría que hacer su propio análisis de accesibilidad es una mala idea.

Entonces, para ser práctico necesitas:

  • reconsidere su diseño para que no haga cosas basadas en la accesibilidad, o
  • vivir con las consecuencias de usar finalizar.

La primera opción es claramente la mejor, en mi opinión.

Tal vez pueda subclase Phantomreference y almacenar los datos necesarios para las acciones finales.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top