24

簡単な質問だと思います。私は両方の方法で例を見てきました。問題は、「フィールドに注釈を付けられないのはなぜですか?」ということです。例を挙げましょう....

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

私は両方の方法の例を見てきました。ただし、この 2 番目の例を実行すると、次の結果が得られます...

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行目がマークされている)のスケルトンです....

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

ここで何が起こっているのか誰にも分かりますか?

4

5 に答える 5

35

パフォーマンスと設計の観点からは、getter セッターはメソッドではなく、フィールドに配置された場合にリフレクションを使用して呼び出されるため、メンバー変数よりも getter で注釈を使用することをお勧めします。また、検証や休止状態のその他の機能を使用する場合は、すべての注釈をあちこちに分散させるのではなく、1 か所にまとめます。

私の推奨事項は、メンバー変数ではなくメソッドを使用することです。

ドキュメントから

フィールドにアノテーションを付けるかメソッドにアノテーションを付けるかに応じて、Hibernate が使用するアクセス タイプはフィールドまたはプロパティになります。EJB3 仕様では、アクセスされる要素タイプ (プロパティ アクセスを使用する場合は getter メソッド、フィールド アクセスを使用する場合はフィールド) でアノテーションを宣言する必要があります。フィールドとメソッドの両方で EJB3 アノテーションを混在させることは避ける必要があります。Hibernate は @Id または @EmbeddedId の位置からアクセス タイプを推測します。

于 2008-11-20T23:05:26.810 に答える
12

あなたは私を正しいトラックのツールキットに乗せました。ありがとう。これが取り引きです... もちろん、私の不自然な例にはストーリー全体が含まれていませんでした。私の Widget クラスは、実際には、私が示した例よりもはるかに大きくなりました。いくつかの追加のフィールド/ゲッターがあり、注釈をミックスしていました。そのため、フィールドで @Id に注釈を付けていましたが、ゲッターで他の人に注釈を付けていました。

したがって、この話の教訓は、注釈の場所を混在させることはできないということです。すべての注釈がフィールド上にあるか、getter メソッド上にあります。長年の Java と Hibernate、Annotations の新機能。毎日何かを学びましょう。

Google のことを知ったら、これは役に立ちました - http://chstath.blogspot.com/2007/05/field-access-vs-property-access-in-jpa.html

もちろん、これにより、デザインとパフォーマンスの観点からどちらが優れているかという疑問が生じます。

于 2008-11-20T17:49:16.353 に答える
1

長いリーチですが、古い*.hbm.xmlファイルが浮かんでいますか?

おそらく、 ?の代わりに間違った設定を取得してdefault-access使用している可能性があります。propertyfield

于 2008-11-20T17:20:25.070 に答える
1

これは、アクセス タイプと関連するベスト プラクティスを理解するのに役立つ非常に優れたリンクです。

Hibernate での @AccessType の理解

于 2010-04-27T17:29:52.047 に答える
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;}
}
于 2008-11-20T16:26:22.950 に答える