2010-04-20 22 views
43

Tenemos algunos métodos getter de Hibernate anotados con @Column y @Basic.¿Hibernate siempre necesita un setter cuando hay un getter?

Recibimos una excepción si no tenemos el colocador correspondiente. ¿Por qué es esto?

En nuestro caso derivamos el valor devuelto por el captador (para almacenarlo en el DB) y el colocador no tiene un propósito funcional. Así que solo tenemos un método vacío para evitar la condición de error.

+0

objetos del modelo Justo Autogenerar. Eclipse, Dali y/o Hibernatetools pueden hacer esto con unos pocos clics. No es necesario dedicar horas a escribir getters/setters ni preocuparse por su corrección y presencia. – BalusC

Respuesta

57

Como han mencionado otros, si anota un método getter de propiedad, entonces Hibernate usa el setter cuando lee valores de la base de datos. Básicamente, Hibernate supone que todo lo que está escribiendo en la base de datos necesitará leerse en la base de datos. Esto implica que si anota un getter, entonces necesita llamar a un setter cuando lee el objeto de la base de datos.

Puede hacer que el colocador sea privado (Hibernate usará la reflexión para acceder al colocador). Esta es una gran manera de preservar el contrato de su clase mientras sigue usando Hibernate para el mapeo relacional.

Si el campo se deriva de otras propiedades de la clase, ¿por qué lo está almacenando en la base de datos? Puede usar la anotación @Transient para marcar el campo que no debe almacenarse en la base de datos. Incluso puede usar la anotación @Formula para que Hibernate obtenga el campo por usted (lo hace mediante el uso de la fórmula en la consulta que envía a la base de datos).

+1

La anotación '@ Transient' en el getter es todo lo que se necesita – mirelon

1

Hibernate usa el método set para inicializar la entidad que está leyendo desde su base de datos.

Tal vez, si haces modificadores de acceso de campos de entidad default o protected o public, entonces Hibernate inicializar los campos directamente sin utilizar colocador (he leído algo al respecto, pero no estoy seguro de que funcione). Pero usar setter es una forma mucho más preferida.

+0

Lo que pasa es que solo estamos escribiendo datos en el DB, nunca leyendo ...pero supongo que Hibernate no lo sabe;) –

+0

Desafortunadamente no, el modificador "privado" no obliga a Hibernate a utilizar setters :( – Andremoniy

8

Debe anotar sus clases con el @Entity(access = AccessType.FIELD) y anotar sus atributos. Esto debería solucionar tu problema. El colocador es la mejor manera de apoyar la refactorización. Y cuál es el problema de tener al pequeño setter allí.

+3

Simplemente ponga las anotaciones en los atributos en lugar del getter, entonces debería funcionar también (Lea el documento de anotación sobre el tipo de acceso). – khmarbaise

+0

No hay problema con tener el setter per se ... es solo código extra ... solo estamos usando Hibernate para escribir en el db, nunca para leer ... –

+1

Tenga en cuenta que cambiar el tipo de acceso de property to field puede tener un efecto secundario. Hibernate ya no usará los getters y setters, sino que accederá a los campos directamente a través de la reflexión, lo que significa que si tiene alguna lógica especial en sus getters y setters, ya no se llamará. – Jherico

-2

Si no usa setters y usa atributos privados, Hibernate debería recuperar los campos por reflexión y hacer field.setAccessible (true). No creo que Hibernate haga eso.

No sé si realmente podemos decirle a Hibernate que haga eso, pero por lo que recuerdo, la configuración predeterminada usa setters ... Ponga un log/sysout en un conjunto y verá que usa el colocador.

+2

-1 porque si el campo o la propiedad es privado, Hibernate hace exactamente eso (use field.setAccessible (cierto)). –

+0

En realidad, estoy bastante seguro de que al usar beans JPA/entity con todos los atributos privados, hibernate (creo que 3.4) estaba usando el setter ... Pero quizás si no hay setter lo hace ... no sé. .. –

4

acceso = campo si no desea utilizar los emisores

<id name="countryId" column="id" type="int"> 
<generator class="increment"> 
    </generator> 

</id> 
<property name="name" column="name" access="field" type="string"></property> 
<property name="countryCode" column="country_code" access= "field" type="string"></property> 

Cuestiones relacionadas