Hibernate 注释放置问题
Posted
技术标签:
【中文标题】Hibernate 注释放置问题【英文标题】:Hibernate Annotation Placement Question 【发布时间】:2010-09-23 06:46:36 【问题描述】:我有一个我认为很简单的问题。我已经看到了两种方式的例子。问题是 - “为什么我不能将我的注释放在字段上?”。举个例子吧……
@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(Native Method) 在 sun.reflect.NativeMethodAccessorImpl.invoke(未知来源) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(未知来源) 在 java.lang.reflect.Method.invoke(未知来源) ...这是HibernateSessionFactory
的骨架(第 25 行已标记)....
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;
有人知道这里发生了什么吗?
【问题讨论】:
也许你在第 22 行的 catch 块中吞下了一个异常? 【参考方案1】:从性能和设计的角度来看,在 getter 上使用注解比成员变量更好,因为如果将 getter setter 放在字段上,则使用反射调用,而不是方法。此外,如果您计划使用 hibernate 的验证和其他功能,您可以将所有注释放在一个地方,而不是将它们分散在一个地方。
我的建议是使用方法而不是成员变量。
来自文档
根据你是注释字段还是方法,Hibernate 使用的访问类型将是字段或属性。 EJB3 规范要求您在将要访问的元素类型上声明注释,即如果您使用属性访问,则为 getter 方法,如果您使用字段访问,则为字段。应避免在字段和方法中混合使用 EJB3 注释。 Hibernate 会根据@Id 或@EmbeddedId 的位置猜测访问类型。
【讨论】:
回复:because the getter setters are called using reflection
,慢了多少?您是否粗略估计使用反射而不是字段的 getter 和 setter 需要多长时间?谢谢
我投了反对票,因为您没有回答为什么字段访问在 OP 的示例中不起作用。此外,您声称存在速度差异,但没有进行测试。 AFAIK,无论您注释字段还是方法,休眠都使用反射。另请参阅:***.com/questions/332591
@Navin +1 ***.com/questions/332591 表示性能没有显着差异。【参考方案2】:
你让我走上了正确的轨道工具包。谢谢。这是交易......当然,我人为的例子并没有包括整个故事。我的 Widget 类实际上比我给出的示例大得多。我有几个额外的字段/吸气剂,我是 MIXING 我的注释。所以我在字段上注释了@Id,但其他人在 getter 上被注释了。
所以这个故事的寓意是你不能混合注释位置。所有注释都在字段上,或者它们在 getter 方法上。长期使用 Java 和 Hibernate,是 Annotations 的新手。每天学习一些东西。
一旦我知道谷歌需要做什么,我就会发现这很有帮助 - http://chstath.blogspot.com/2007/05/field-access-vs-property-access-in-jpa.html
当然,这带来了一个问题,即从设计和性能的角度来看哪个更好。
【讨论】:
【参考方案3】:一个很长的范围,但是你有一个旧的*.hbm.xml
文件吗?
也许它可能为default-access
选择了错误的设置并使用property
而不是field
?
【讨论】:
【参考方案4】:这是一个非常好的链接,可以帮助您了解访问类型和相关的最佳实践!
了解@AccessType in Hibernate
【讨论】:
这个问题有点老了,但这里有一个新链接,提供了一些有价值的相关信息 - dzone.com/links/r/…【参考方案5】:如果您执行以下操作,它是否有效:
@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;
【讨论】:
不。如果“按以下”表示@GeneratedValue 之后的空行。结果相同。 (感谢您的快速回复!)。 没问题。我原以为如果您以编程方式配置 Hibernate,那么您需要告诉 AnnotationConfiguration 在哪里可以找到带注释的类。请参阅以下内容:hibernate.org/hib_docs/annotations/reference/en/html_single/…以上是关于Hibernate 注释放置问题的主要内容,如果未能解决你的问题,请参考以下文章
使用 hibernate、hibernate 注释和 ehcache 的 Maven 依赖项是啥?
带有注释的 Spring + Hibernate:没有 Hibernate Session 绑定到线程