Hibernate アノテーションの配置に関する質問 質問する

Hibernate アノテーションの配置に関する質問 質問する

単純な質問だと思います。両方の例を見てきました。質問は「なぜフィールドに注釈を配置できないのか?」です。例を挙げてみましょう...

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

ここで何が起こっているのか分かる人はいますか?

ベストアンサー1

パフォーマンスと設計の観点から、ゲッターにアノテーションを使用する方がメンバー変数を使用するよりも良いアイデアです。これは、ゲッター セッターがメソッドではなくフィールドに配置されている場合、リフレクションを使用して呼び出されるためです。また、検証や Hibernate のその他の機能を使用する予定の場合は、アノテーションをあちこちに分散させるのではなく、すべてのアノテーションを 1 か所にまとめることができます。

メンバー変数ではなくメソッドを使用することをお勧めします。

ドキュメントより

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

おすすめ記事