2008-11-20 43 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