Hibernar anotaciones: ¿cuál es mejor, el acceso a campos o a propiedades?

Resuelto Martin OConnor asked hace 15 años • 23 respuestas

Esta pregunta está algo relacionada con la pregunta sobre la ubicación de las anotaciones de Hibernate .

¿Pero quiero saber cuál es mejor ? ¿Acceso a través de propiedades o acceso a través de campos? ¿Cuales son las ventajas y desventajas de cada uno?

Martin OConnor avatar Feb 27 '09 19:02 Martin OConnor
Aceptado

Hay argumentos para ambos, pero la mayoría de ellos surgen de ciertos requisitos del usuario "¿Qué sucede si necesita agregar lógica?" o "xxxx rompe la encapsulación". Sin embargo, nadie ha comentado realmente la teoría ni ha dado un argumento debidamente razonado.

¿Qué hace realmente Hibernate/JPA cuando persiste un objeto? Bueno, persiste el ESTADO del objeto. Eso significa almacenarlo de manera que pueda reproducirse fácilmente.

¿Qué es la encapsulación? Encapsulaciones significa encapsular los datos (o el estado) con una interfaz que la aplicación/cliente puede usar para acceder a los datos de forma segura, manteniéndolos consistentes y válidos.

Piense en esto como MS Word. MS Word mantiene un modelo del documento en la memoria: el ESTADO del documento. Presenta una interfaz que el usuario puede usar para modificar el documento: un conjunto de botones, herramientas, comandos de teclado, etc. Sin embargo, cuando persiste (Guarda) ese documento, guarda el estado interno, no el conjunto de pulsaciones de teclas y mouse. clics utilizados para generarlo.

Guardar el estado interno del objeto NO rompe la encapsulación; de lo contrario, no comprende realmente qué significa encapsulación y por qué existe. En realidad, es como la serialización de objetos.

Por esta razón, EN LA MAYORÍA DE LOS CASOS, lo apropiado es persistir los CAMPOS y no los ACCESORES. Esto significa que un objeto se puede recrear con precisión desde la base de datos exactamente como se almacenó. No debería necesitar ninguna validación, porque esto se hizo en el original cuando se creó y antes de que se almacenara en la base de datos (a menos, ¡Dios no lo quiera, que esté almacenando datos no válidos en la base de datos!). Del mismo modo, no debería ser necesario calcular valores, ya que ya se calcularon antes de almacenar el objeto. El objeto debería verse exactamente como tenía antes de guardarlo. De hecho, al agregar elementos adicionales a los captadores/definidores, en realidad está aumentando el riesgo de recrear algo que no sea una copia exacta del original.

Por supuesto, esta funcionalidad se agregó por una razón. Puede haber algunos casos de uso válidos para conservar los descriptores de acceso; sin embargo, normalmente serán poco frecuentes. Un ejemplo puede ser que desee evitar que un valor calculado persista. Sin embargo, es posible que desee preguntarse por qué no lo calcula a pedido en el captador del valor, o no lo inicializa de manera perezosa en el captador. Personalmente, no se me ocurre ningún buen caso de uso y ninguna de las respuestas aquí realmente da una respuesta de "Ingeniería de software".

Martin avatar May 21 '2011 21:05 Martin

Prefiero el acceso al campo, porque de esa manera no me veo obligado a proporcionar captadores/definidores para cada propiedad.

Una encuesta rápida a través de Google sugiere que el acceso al campo es mayoritario (por ejemplo, http://java.dzone.com/tips/12-feb-jpa-20-why-accesstype ).

Creo que el acceso al campo es el modismo recomendado por Spring, pero no puedo encontrar una referencia que lo respalde.

Hay una pregunta SO relacionada que intentó medir el rendimiento y llegó a la conclusión de que "no hay diferencia".

duffymo avatar Feb 27 '2009 12:02 duffymo

Aquí hay una situación en la que TIENES que usar descriptores de acceso a la propiedad. Imagine que tiene una clase abstracta GENÉRICA con muchas bondades de implementación para heredar en 8 subclases concretas:

public abstract class Foo<T extends Bar> {

    T oneThing;
    T anotherThing;

    // getters and setters ommited for brevity

    // Lots and lots of implementation regarding oneThing and anotherThing here
 }

Ahora bien, ¿exactamente cómo deberías anotar esta clase? La respuesta es NO PUEDE anotarlo en absoluto con acceso a campos o propiedades porque no puede especificar la entidad de destino en este momento. TIENES que anotar las implementaciones concretas. Pero dado que las propiedades persistentes se declaran en esta superclase, DEBE utilizar el acceso a propiedades en las subclases.

El acceso a campos no es una opción en una aplicación con superclases genéricas abstractas.

Dave avatar Jul 06 '2010 06:07 Dave