programacion - java and hibernate
Pregunta de colocaciĆ³n de anotaciĆ³n de Hibernate (5)
Tengo lo que creo que es una pregunta simple. He visto ejemplos en ambos sentidos. La pregunta es: "¿por qué no puedo colocar mis anotaciones en el campo?". Dejame darte un ejemplo....
@Entity
@Table(name="widget")
public class Widget {
private Integer id;
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
public Integer getId() { return this.id; }
public Integer setId(Integer Id) { this.id = id;}
}
El código anterior funciona bien (suponiendo que no haya un error tipográfico). Cuando la anotación se coloca en el captador de la propiedad, todo es perfecto.
Sin embargo, eso me parece incomodo. En mi opinión, es más limpio colocar la anotación en el campo, así que ...
@Entity
@Table(name="widget")
public class Widget {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
public Integer getId() { return this.id; }
public Integer setId(Integer Id) { this.id = id;}
}
He visto ejemplos de ambas maneras. Sin embargo, cuando ejecuto este segundo ejemplo, recibo lo siguiente ...
java.lang.NullPointerException at com.widget.util.hibernate.HibernateSessionFactory$ThreadLocalSession.initialValue(HibernateSessionFactory.java:25) at com.widget.util.hibernate.HibernateSessionFactory$ThreadLocalSession.initialValue(HibernateSessionFactory.java:1) at java.lang.ThreadLocal$ThreadLocalMap.getAfterMiss(Unknown Source) at java.lang.ThreadLocal$ThreadLocalMap.get(Unknown Source) at java.lang.ThreadLocal$ThreadLocalMap.access$000(Unknown Source) at java.lang.ThreadLocal.get(Unknown Source) at com.widget.util.hibernate.HibernateSessionFactory.get(HibernateSessionFactory.java:33) at com.widget.db.dao.AbstractDao.(AbstractDao.java:12) at com.widget.db.dao.WidgetDao.(WidgetDao.java:9) at com.widget.db.dao.test.WidgetDaoTest.findById(WidgetDaoTest.java:17) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) ...
Aquí está el esqueleto de HibernateSessionFactory
(la línea 25 está marcada) ...
protected Session initialValue() {
SessionFactory sessionFactory = null;
try {
Configuration cfg = new AnnotationConfiguration().configure();
String url = System.getProperty("jdbc.url");
if (url != null) {
cfg.setProperty("hibernate.connection.url", url);
}
sessionFactory = cfg.buildSessionFactory();
}
catch (Exception e) {
}
Session session = sessionFactory.openSession(); // LINE 25
return session;
}
Alguien tiene una idea de lo que está pasando aquí?
¡Este es un enlace muy bueno que puede ayudarlo a comprender los accesos y las mejores prácticas relacionadas!
Understanding @AccessType en Hibernate
Desde una perspectiva de rendimiento y diseño, el uso de anotaciones en getters es una mejor idea que las variables miembro, porque los setters de getters se llaman usando el reflejo si se colocan en el campo, que como un método. Además, si planea usar la validación y otras funciones de hibernación, tendrá todas las anotaciones en un solo lugar, en lugar de dispersarlas por todos lados.
Mi recomendación es ir con métodos no variables de miembros.
De la documentación
Dependiendo de si anota campos o métodos, el tipo de acceso utilizado por Hibernate será campo o propiedad. La especificación EJB3 requiere que usted declare las anotaciones en el tipo de elemento al que se accederá, es decir, el método getter si usa el acceso a la propiedad, el campo si usa el acceso al campo. Debe evitarse mezclar anotaciones EJB3 en ambos campos y métodos. Hibernate adivinará el tipo de acceso desde la posición de @Id o @EmbeddedId.
Funciona si haces lo siguiente:
@Entity
@Table(name="widget")
public class Widget {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
public Integer getId() { return this.id; }
public Integer setId(Integer Id) { this.id = id;}
}
Me pusiste en el kit de herramientas adecuado. Gracias. Aquí está el trato ... Por supuesto, mi ejemplo artificial no incluía toda la historia. Mi clase de Widget en realidad era mucho más grande que el ejemplo que di. Tengo varios campos / getters adicionales y estaba MIXING mis anotaciones. Así que estaba anotando @Id en el campo, pero otros estaban siendo anotados en el getter.
Entonces, la moraleja de la historia es que no puedes mezclar lugares de anotación. O bien todas las anotaciones están en los campos o están en los métodos getter. Long time Java and Hibernate, nuevo en Anotaciones. Aprende algo todos los días.
Una vez que supe a qué Google buscar, encontré esto que fue útil - http://chstath.blogspot.com/2007/05/field-access-vs-property-access-in-jpa.html
Por supuesto, esto ahora plantea la pregunta de cuál es mejor desde perspectivas de diseño y rendimiento.
Un largo alcance, pero ¿tiene un antiguo archivo *.hbm.xml
flotando?
Tal vez podría estar recogiendo la configuración incorrecta para default-access
por default-access
y el uso de property
lugar de field
?