estoy acaba de empezar con Hibernate, y todos los ejemplos que estoy viendo hasta ahora se parecen mucho a la clase particular en la documentación de Hibernate:¿Hay alguna manera de declarar los campos finales para los objetos gestionados por Hibernate?
package org.hibernate.tutorial.domain;
import java.util.Date;
public class Event {
private Long id;
private String title;
private Date date;
public Event() {}
/* Accessor methods... */
}
Específicamente: ninguno de los campos se declaran como final
, y debe haber un constructor sin argumentos para que el marco de Hibernate pueda instanciar la clase y establecer sus campos.
Pero aquí está la cosa - me realmente no me gusta hacer mis clases mutables de cualquier manera siempre que puedo evitarlo (Prácticas de Java: inmutables objetos hacen un argumento bastante fuerte para hacer esto). Así que ¿hay alguna forma de hacer que Hibernate funcione incluso si tuviera que declarar cada uno de los campos 'final'?
Entiendo que Hibernate utiliza Reflection para instanciar sus clases y, por lo tanto, necesita poder invocar un constructor de algún tipo sin correr el riesgo de elegir el constructor equivocado o pasar el valor incorrecto a uno de sus parámetros, por lo probablemente sea más seguro invocar el constructor no-arg y establecer cada campo de uno en uno. Sin embargo, ¿no debería ser posible proporcionar la información necesaria a Hibernate para que pueda instanciar con seguridad objetos inmutables?
public class Event {
private final Long id;
private final String title;
private final Date date;
public Event(@SetsProperty("id") Long id,
@SetsProperty("title") String title,
@SetsProperty("date") Date date) {
this.id = id;
this.title = title;
this.date = new Date(date.getTime());
}
/* Accessor methods... */
}
El @SetsProperty
anotación es, por supuesto ficticio, pero no parece que debería estar fuera de su alcance.
+1: Bonita idea sobre el uso de una clase contenedora: parece que sería una buena solución cuando se necesitan clases/campos finales. Incluso se podría evitar la ambigüedad sobre qué versión (mutable vs. wrapper) se debería usar externamente haciendo que la versión mutable sea visible solo para las clases de acceso a datos. En cuanto a la utilización final, mi razón principal es que a menudo es más fácil garantizar (en lugar de suponer) que cada campo se asigna exactamente una vez en la construcción. Tenemos una gran cantidad de datos que deben ser constantes durante toda la vida de la JVM que los utiliza, por lo que es útil aclarar esto. –
Los campos finales evitan que un usuario asigne accidentalmente algo que no debería tener e introduce un error sutil. Si sabes que algo nunca cambiará, querrás que sea definitivo. En el futuro, si descubres que debería cambiar, siempre puedes eliminar esa restricción. – corsiKa