Hibernate注释放置问题

时间:2008-11-20 16:20:45

标签: java hibernate annotations

我认为这是一个简单的问题。我已经看过两种方式的例子。问题是 - “为什么我不能把我的注释放在场上?”。让我举个例子......

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

任何人都知道这里发生了什么?

5 个答案:

答案 0 :(得分:31)

从性能和设计的角度来看,在getter上使用注释比成员变量更好,因为如果放置在字段上,则使用反射调用getter setter而不是方法。此外,如果您打算使用hibernate的验证和其他功能,您将在一个地方获得所有注释,而不是将它们分散到各处。

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

来自文档

  

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

答案 1 :(得分:11)

你让我使用正确的轨道工具包。谢谢。这是交易......当然,我的人为例子并不包括整个故事。我的Widget类实际上比我给出的示例大得多。我有几个额外的字段/ getter,我 MIXING 我的注释。所以我在场上注释@Id,但其他人正在注意吸气器。

故事的寓意是你不能混合注释位置。要么所有注释都在字段上,要么它们都在getter方法上。 Java和Hibernate很长时间,Annotations的新功能。每天都在学习。

一旦我知道谷歌会发生什么,我就会发现这很有帮助 - http://chstath.blogspot.com/2007/05/field-access-vs-property-access-in-jpa.html

当然,现在提出了一个问题,即从设计和性能角度来看哪个更好。

答案 2 :(得分:1)

长距离,但你有一个旧的*.hbm.xml文件浮动?

也许它可能会为default-access选择错误的设置并使用property代替field

答案 3 :(得分:1)

这是一个非常好的链接,可以帮助您理解访问类型和重新发布的最佳实践!

解决@AccessType in Hibernate

答案 4 :(得分: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;}
}