Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/314.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 当使用JPA映射类时,为什么要在getter或setter上添加注释?_Java_Hibernate_Jpa_Annotations_Mapping - Fatal编程技术网

Java 当使用JPA映射类时,为什么要在getter或setter上添加注释?

Java 当使用JPA映射类时,为什么要在getter或setter上添加注释?,java,hibernate,jpa,annotations,mapping,Java,Hibernate,Jpa,Annotations,Mapping,主题说明了一切。。。到目前为止,我认为人们在getter和/或setter上声明注释没有任何好处。对我来说,这样做的唯一缺点是将注释分散在类上,这会使类更不可读 将注释放在字段上可以明显减少需要帮助时要发布的代码量。不过这只是一个小小的优势。但是在方法上添加注释对我来说毫无用处。在方法上添加注释会迫使JPA通过方法访问属性。当对象的内部状态与数据库架构不同时,这是有意义的: @Entity public class Employee { private String firstName;

主题说明了一切。。。到目前为止,我认为人们在getter和/或setter上声明注释没有任何好处。对我来说,这样做的唯一缺点是将注释分散在类上,这会使类更不可读


将注释放在字段上可以明显减少需要帮助时要发布的代码量。不过这只是一个小小的优势。但是在方法上添加注释对我来说毫无用处。

在方法上添加注释会迫使JPA通过方法访问属性。当对象的内部状态与数据库架构不同时,这是有意义的:

@Entity
public class Employee {
    private String firstName;
    private String lastName;

    @Column(name = "EMP_NAME") // Due to legacy database schema
    public String getName() {
        return fisrtName + " " + lastName;
    }

    public void setName(String name) {
        ...
    }

    ... Getters and setters for firstName and lastName with @Transient ...
}
在JPA2.0中,您可以使用
@access
在细粒度级别指定访问类型:

@Entity @Access(AccessType.FIELD)
public class Employee {
    @Access(AccessType.PROPERTY) @Column(name = "EMP_NAME")
    public String getName() { ... }
    ... other properties have field access ...
}
当使用JPA映射类时,为什么要在getter或setter上添加注释

如前所述,如果需要,使用属性访问允许在getter中添加逻辑

但是由于问题被标记,我将提到另一个(巨大的)好处:属性访问允许您在不初始化代理的情况下调用
foo.getId()
。使用字段访问时,无法获得相同的行为。Emmanuel Bernard对现场访问限制的解释如下:

这是不幸的,但也是意料之中的。这是现场级访问的限制之一。 基本上,我们无法知道getId()实际上只访问id字段。所以我们需要加载整个对象以确保安全

因此,是的,使用属性访问会使代码更难阅读,例如,您必须浏览整个类以查看是否有任何
@Transient
。但对我来说,好处(至少有)远远超过了缺点

相关问题
工具书类

    • 给出的答案是正确的。注释方法而不是特性将为您提供:

    • 使用getId()的权限,如果它被标记为@Id值,则可以从代理对象获取外键值,而无需实际从DB加载它

    • 您可以创建用于更新不在数据库中的内部对象状态的getter/setter。我在从DB中检索压缩状态时使用了这个方法,我想在对象内将其解压缩为更可用的内部成员数据。setter和getter设置并获取压缩状态,DB和Hibernate不“知道”未压缩的内部成员

    • 我遇到了一个缺点:


      你的二传手必须非常简单。Hibernate期望他们通过直接分配给成员数据来完成任务。“setCategory”方法不仅设置类别,而且更新相关的category对象以显示关系,这可能会给您带来麻烦。

      我在getter/setter上使用注释,因为我有一个与实现分离的API,我想让API部分完全无框架,允许我切换框架或提供不同的实现。例如,现在我正在使用SpringDataJPA,但是有了下面的API,我可以很容易地切换到SpringJDBC或任何其他框架

      我所做的是为控制器、存储库和实体定义接口,例如:

      public interface MyEntityController<T extends MyEntity> {
          Iterable<T> listEntities();
          T getEntity(Long id);
      }
      
      public interface MyEntityService<T extends MyEntity> {
          Iterable<T> findAll();
          T findById(Long id);
      }
      
      public interface MyEntityRepository<T extends MyEntity> {
          Iterable<T> findAll();
          T findOne(Long id);
      }
      
      // no JPA annotations here
      public abstract class MyEntity {
          protected Long id;
          protected String myField;
      }
      
      公共接口MyEntityController{
      Iterable listenties();
      T getEntity(长id);
      }
      公共接口MyEntityService{
      Iterable findAll();
      T findById(长id);
      }
      公共接口MyEntityRepository{
      Iterable findAll();
      T findOne(长id);
      }
      //这里没有JPA注释
      公共抽象类MyEntity{
      保护长id;
      受保护字符串myField;
      }
      
      接下来,我将按照如下方式实现MyEntity,并将MyEntityImpl用于控制器、服务和存储库实现:

      @Entity
      public class MyEntityImpl extends MyEntity {
          @Id public long getId() { return id; }
          @Column public String getMyField() { return myField };
          // setters, etc
      }
      
      @Repository
      public interface MyEntityRepositoryImpl extends MyEntityRepository, JPARepository<MyEntityImpl, Long> {
      }
      
      @实体
      公共类MyEntityImpl扩展了MyEntity{
      @Id public long getId(){return Id;}
      @列公共字符串getMyField(){return myField};
      //二传手等
      }
      @存储库
      公共接口MyEntityRepositoryImpl扩展了MyEntityRepository,JPARepository{
      }
      

      我已经测试过了,效果很好。仅仅用
      @Entity
      注释
      MyEntityImpl
      是不可行的,因为超类需要是
      @MappedSuperclass

      我认为不支持对setter进行注释,因为使用setter的反射来确定字段的类类型更为困难。对于getter,您所要做的就是检查方法的返回类型。但对于setter,如果要向其传递多个参数,该怎么办?