【问题标题】:Hibernate Annotation Placement QuestionHibernate 注释放置问题
【发布时间】:2010-09-23 06:46:36
【问题描述】:

我有一个我认为很简单的问题。我已经看到了两种方式的例子。问题是 - “为什么我不能将我的注释放在字段上?”。举个例子吧……

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

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

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

@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 在 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(Native Method) 在 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;
}

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

【问题讨论】:

  • 也许你在第 22 行的 catch 块中吞下了一个异常?

标签: java hibernate annotations


【解决方案1】:

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

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

来自文档

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

【讨论】:

  • 回复:because the getter setters are called using reflection,慢了多少?您是否粗略估计使用反射而不是字段的 getter 和 setter 需要多长时间?谢谢
  • 我投了反对票,因为您没有回答为什么字段访问在 OP 的示例中不起作用。此外,您声称存在速度差异,但没有进行测试。 AFAIK,无论您注释字段还是方法,休眠都使用反射。另请参阅:stackoverflow.com/questions/332591
  • @Navin +1 stackoverflow.com/questions/332591 表示性能没有显着差异。
【解决方案2】:

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

所以这个故事的寓意是你不能混合注释位置。所有注释都在字段上,或者它们在 getter 方法上。长期使用 Java 和 Hibernate,是 Annotations 的新手。每天学习一些东西。

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

当然,这带来了一个问题,即从设计和性能的角度来看哪个更好。

【讨论】:

    【解决方案3】:

    一个很长的范围,但是你有一个旧的*.hbm.xml 文件吗?

    也许它可能为default-access 选择了错误的设置并使用property 而不是field

    【讨论】:

      【解决方案4】:

      这是一个非常好的链接,可以帮助您了解访问类型和相关的最佳实践!

      了解@AccessType in Hibernate

      【讨论】:

      • 这个问题有点老了,但这里有一个新链接,提供了一些有价值的相关信息 - dzone.com/links/r/…
      【解决方案5】:

      如果您执行以下操作,它是否有效:

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

      【讨论】:

      • 不。如果“按以下”表示@GeneratedValue 之后的空行。结果相同。 (感谢您的快速回复!)。
      • 没问题。我原以为如果您以编程方式配置 Hibernate,那么您需要告诉 AnnotationConfiguration 在哪里可以找到带注释的类。请参阅以下内容:hibernate.org/hib_docs/annotations/reference/en/html_single/…
      猜你喜欢
      • 2021-03-22
      • 2020-02-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-20
      • 1970-01-01
      • 1970-01-01
      • 2012-08-07
      相关资源
      最近更新 更多