2008-11-20 57 views
21

我有我认为是一个简单的问题。我看过两个例子。问题是 - “为什么我不能把我的注释放在现场?”。我给大家举一个例子....Hibernate Annotation Placement问题

@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;} 
} 

上面的代码工作正常(假设不是一个错字在那里)。当注释放置在属性的吸气器上时,一切都是完美的。

但是,这对我来说似乎很尴尬。在我的印象是清洁的地方标注在球场上,像这样 -

@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 
    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) 
    ... 

这里的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; 
} 

人有一个想法是怎么回事在这?

+0

也许你在catch块中的第22行吞咽异常? – johnstok 2008-11-20 16:40:00

回答

31

从性能和设计的角度来看,对getter使用注释比成员变量更好,因为如果将getter设置器放置在字段上而不是方法,则会使用反射器来调用getter setter。同样,如果你打算使用hibernate的验证和其他功能,你将在一个地方有所有的注释,而不是散布在整个地方。

我的建议去与方法不是成员变量。

从文档

根据您是否注释字段或方法,Hibernate使用的访问类型将字段或属性。EJB3规范要求您对将要访问的元素类型声明注释,例如,如果使用属性访问,则使用getter方法;如果使用字段访问,则使用该字段。应该避免在这两个字段和方法中混合使用EJB3注释。 Hibernate将猜测来自@Id或@EmbeddedId位置的访问类型。

+2

re:`因为getter setters被称为使用反射`,多少慢?你是否粗略地估计了使用Reflection需要多长时间,而不是字段的getter和setter?谢谢 – 2014-09-09 16:41:49

0

请问,如果你做了以下它的工作:

@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;} 
} 
+1

不是。如果“通过以下方式”,则表示@GeneratedValue后面有一个空行。同样的结果。 (并感谢您的快速响应!)。 – SteveT 2008-11-20 16:27:52

+0

没问题。我会想,如果你以编程方式配置Hibernate,那么你需要告诉AnnotationConfiguration在哪里找到你的注释类。 请参阅以下内容:http://www.hibernate.org/hib_docs/annotations/reference/en/html_single/#setup-configuration – Jonathan 2008-11-20 16:39:03

1

一个长距离,但你有一个旧的*.hbm.xml文件左右浮动?

也许它可能是default-access采用错误设置,并使用property而不是field

10

你让我在正确的轨道工具包。谢谢。这就是协议......当然,我所做的例子并不包括整个故事。我的Widget类实际上比我给出的例子大得多。我有几个额外的领域/获得者,我是MIXING我的注释。所以我在字段上注解了@Id,但是其他人被注解在getter上。

故事的寓意是你不能混合注释位置。所有注释都在字段上,或者它们在getter方法上。很长一段时间Java和Hibernate,新注解。每天学习一些东西。

有一次,我知道该怎么谷歌为我碰到这里面是有帮助的来到 - http://chstath.blogspot.com/2007/05/field-access-vs-property-access-in-jpa.html

当然,这现在带来了作为是从设计和性能的角度更好的问题。

+0

很棒.......... – nobalG 2014-12-17 10:49:10