我有一个简单的问题。我已经看过两种方式的例子。问题是-“为什么不能在字段上放置注释?”。让我举一个例子....
@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;} }
上面的代码可以正常工作(假设那里没有错字)。当将注释放在属性的getter上时,一切就完美了。
但是,这对我来说似乎很尴尬。在我看来,将注解放在字段上比较干净,就像这样-
@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;} }
我已经看到了两种方式的示例。但是,当我运行第二个示例时,我得到以下信息…
java.lang.NullPointerException 在com.widget.util.hibernate.HibernateSessionFactory $ ThreadLocalSession.initialValue(HibernateSessionFactory.java:25) 在com.widget.util.hibernate.HibernateSessionFactory $ ThreadLocalSession.initialValue(HibernateSessionFactory.java:1) 在java.lang.ThreadLocal $ ThreadLocalMap.getAfterMiss(未知来源) 在java.lang.ThreadLocal $ ThreadLocalMap.get(未知来源) 在java.lang.ThreadLocal $ ThreadLocalMap.access $ 000(未知源) 在java.lang.ThreadLocal.get(未知来源) 在com.widget.util.hibernate.HibernateSessionFactory.get(HibernateSessionFactory.java:33) 在com.widget.db.dao.AbstractDao。(AbstractDao.java:12) 在com.widget.db.dao.WidgetDao。(WidgetDao.java:9) 在com.widget.db.dao.test.WidgetDaoTest.findById(WidgetDaoTest.java:17) 在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)处 在sun.reflect.NativeMethodAccessorImpl.invoke(未知来源) 在sun.reflect.DelegatingMethodAccessorImpl.invoke(未知来源) 在java.lang.reflect.Method.invoke(未知来源) ...
这是HibernateSessionFactory(标有第25行)… 的骨架。
HibernateSessionFactory
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; }
有人知道这里发生了什么吗?
从性能和设计的角度来看,在getter上使用注释比在成员变量上更好,因为与方法相比,使用反射将getter setter调用(如果放置在字段上)。同样,如果您打算使用验证和hibernate的其他功能,则将所有注释都放在一个位置,而不是将它们分散在整个位置。
我的建议是使用方法而不是成员变量。
从文档中
根据您是否注释字段或方法,Hibernate使用的访问类型将是字段或属性。EJB3规范要求您在将要访问的元素类型上声明注释,即,如果使用属性访问,则为getter方法;如果使用字段访问,则为字段。应该避免在字段和方法中混用EJB3注释。Hibernate将从@Id或@EmbeddedId的位置猜测访问类型。