Hibernate 注释放置问题 [英] Hibernate Annotation Placement Question

查看:22
本文介绍了Hibernate 注释放置问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个我认为很简单的问题.我已经看到了两种方式的例子.问题是 - 为什么我不能将我的注释放在字段上?".让我给你举个例子....

@Entity@Table(name="widget")公共类小部件{私有整数 ID;@ID@GeneratedValue(策略=GenerationType.AUTO)公共整数 getId() { 返回 this.id;}public Integer setId(Integer Id) { this.id = id;}}

上面的代码工作正常(假设那里没有拼写错误).当注解放在属性的 getter 上时,一切就完美了.

然而,这对我来说似乎很尴尬.在我看来,将注释放在字段上会更干净,就像这样 --

@Entity@Table(name="widget")公共类小部件{@ID@GeneratedValue(策略=GenerationType.AUTO)私有整数 ID;公共整数 getId() { 返回 this.id;}public Integer setId(Integer Id) { this.id = id;}}

我见过两种方式的例子.但是,当我运行第二个示例时,我得到以下结果...

<前>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(Unknown Source)在 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(Native Method)在 sun.reflect.NativeMethodAccessorImpl.invoke(未知来源)在 sun.reflect.DelegatingMethodAccessorImpl.invoke(未知来源)在 java.lang.reflect.Method.invoke(Unknown Source)...

这里是 HibernateSessionFactory 的骨架(第 25 行被标记)....

protected Session initialValue() {SessionFactory sessionFactory = null;尝试 {配置 cfg = new AnnotationConfiguration().configure();String url = System.getProperty("jdbc.url");如果(网址!= null){cfg.setProperty("hibernate.connection.url", url);}sessionFactory = cfg.buildSessionFactory();}捕获(异常 e){}会话会话 = sessionFactory.openSession();//第 25 行返回会话;}

有人知道这里发生了什么吗?

解决方案

从性能和设计的角度来看,在 getter 上使用注解是比成员变量更好的主意,因为如果将 getter setter 放在字段上,则使用反射调用,比方法.此外,如果您计划使用 Hibernate 的验证和其他功能,您将在一个地方拥有所有注释,而不是将它们分散在所有地方.

我的建议是使用方法而不是成员变量.

来自文档

<块引用>

根据您是注释字段还是方法,Hibernate 使用的访问类型将是字段或属性.EJB3 规范要求您在将要访问的元素类型上声明注释,即如果使用属性访问则声明 getter 方法,如果使用字段访问则声明字段.应避免在字段和方法中混合使用 EJB3 注释.Hibernate 会根据@Id 或@EmbeddedId 的位置猜测访问类型.

I've got what I think is a simple question. I've seen examples both ways. The question is - "why can't I place my annotations on the field?". Let me give you an example....

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

The above code works fine (assuming there's not a typo in there). When the annotation is placed on the getter of the property everything is perfect.

However, that seems awkward to me. In my mind it's cleaner to place the annotation on the field, like so --

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

I've seen examples of both ways. However, when I run this second example I get the following...

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

Here's the skeleton of HibernateSessionFactory (line 25 is marked) ....

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

Anyone have an idea what's going on here?

解决方案

From a performance and design perspective, using annotations on getters is a better idea than member variables, because the getter setters are called using reflection if placed on the field, than a method. Also if you plan to use validation and other features of hibernate, you'll have all the annotations at one place, rather than scattering them all over the place.

My recommendation go with methods not member variables.

From the documentation

Depending on whether you annotate fields or methods, the access type used by Hibernate will be field or property. The EJB3 spec requires that you declare annotations on the element type that will be accessed, i.e. the getter method if you use property access, the field if you use field access. Mixing EJB3 annotations in both fields and methods should be avoided. Hibernate will guess the access type from the position of @Id or @EmbeddedId.

这篇关于Hibernate 注释放置问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆