2008-11-20 4 views
21

У меня есть то, что я считаю простым вопросом. Я видел примеры в обоих направлениях. Вопрос в том, «почему я не могу разместить свои аннотации на поле?». Позвольте мне дать вам пример ....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;} 
} 

Я видел примеры обоих способов. Однако, когда я запускаю этот второй пример я получаю следующее ...

 
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

Может быть, вы глотание исключения в блоке улова на линии 22? – johnstok 2008-11-20 16:40:00

ответ

31

С точки зрения производительности и дизайна использование аннотаций на геттерах является лучшей идеей, чем переменные-члены, потому что геттер-сеттеры вызываются с использованием отражения, если они помещены в поле, чем метод. Также, если вы планируете использовать валидацию и другие функции спящего режима, вы будете иметь все аннотации в одном месте, вместо того, чтобы рассеивать их повсюду.

Моя рекомендация касается методов, не являющихся переменными-членами.

Из документации

В зависимости от аннотирования ли поля или методы, тип доступа, используемый Hibernate будет поле или свойство.Спецификация EJB3 требует, чтобы вы объявляли аннотации по типу элемента, к которому будут обращаться, т. Е. Метод getter, если вы используете доступ к свойствам, поле, если вы используете доступ к полю. Следует избегать микширования аннотаций EJB3 в обоих полях и методах. Hibernate угадает тип доступа с позиции @Id или @EmbeddedId.

+2

re: `потому что приемники getter вызывается с использованием reflection`, насколько медленнее? Есть ли у вас приблизительная оценка того, сколько времени требуется для использования 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

Вы меня нашли на верном пути инструментария. Благодарю. Вот дело ... Конечно, мой надуманный пример не включал всю историю. Класс My Widget на самом деле намного больше, чем пример, который я дал. У меня есть несколько дополнительных полей/геттеров, и я был MIXING мои аннотации. Таким образом, я аннотировал @Id на поле, но другие были аннотированы на геттере.

Итак, мораль этой истории заключается в том, что вы не можете смешивать местоположения аннотаций. Либо все аннотации находятся на полях, либо они находятся на методах геттера. Долгое время Java и Hibernate, новые для Annotations. Учитесь чему-то каждый день.

После того, как я знал, что Google для я наткнулся на это, которое было полезно - http://chstath.blogspot.com/2007/05/field-access-vs-property-access-in-jpa.html

Конечно, это сейчас встает вопрос о том, какой лучше от дизайна и перспективы деятельности.

+0

great .......... – nobalG 2014-12-17 10:49:10

1

Это очень хорошая ссылка, которая может помочь вам в понимании accesstypes и отличных передовых методов!

@AccessType in Hibernate Understading

Смежные вопросы