【问题标题】:What is the correct way to annotate a class with a foreign id using Hibernate?使用 Hibernate 用外国 id 注释类的正确方法是什么?
【发布时间】:2018-02-15 13:16:20
【问题描述】:

我正在努力将现有项目转换为使用 Hibernate。我有这样的课:

@Entity
@Table(name = "user")
public class User {

   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   @Column(name = "user_id")
   private Long userId;

   @Column(name = "group_id_user")
   private Long groupId;

   @Column(name = "name")
   private String name;

   ...
   // getters and setters....   
}

还有这样的课程:

@Entity
@Table(name = "group")
public class Group {

   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   @Column(name = "group_id")
   private Long groupId;

   @Column(name="group_name")
   private String groupName;

   ...
   // getters and setters....   
}

user 表中名为"group_id_user" 的列应该是group 表中名为"group_id" 的列的外键。

类的结构如上所示是否可以或“正确”,或者它们的结构应如下所示以确保外键存在于数据库中?

@Entity
@Table(name = "user")
public class User {

   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   @Column(name = "user_id")
   private Long userId;

   @ManyToOne
   @JoinColumn(name = "group_id_user")
   private Group group;

   @Column(name = "name")
   private String name;

   ...
   // getters and setters....   
}

@Entity
@Table(name = "group")
public class Group {

   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   @Column(name = "group_id")
   private Long groupId;

   @Column(name="group_name")
   private String groupName;

   ...
   // getters and setters....   
}

我尝试过使用这两种格式,但两种方式都有问题。当我使用第一种格式时,我在创建查询时遇到了连接的 HQL 语法问题。当我尝试第二种格式时,我遇到了从数据库中仅获取 User 而没有 Group 的问题,或者从具有 groupId 而不是 Group 对象的 json 对象添加新的 User 时遇到问题。因此,在我花更多时间在两种格式之间来回切换之前,我想确定我应该以哪种方式使用注释以最符合行业标准?

【问题讨论】:

    标签: java mysql hibernate annotations


    【解决方案1】:

    如果您也可以更改列的名称,我会尝试这样的事情:

    @Entity
    @Table(name = "users")
    public class User {
    
       @Id
       @GeneratedValue(strategy = GenerationType.IDENTITY) //This means you will need the database to generate the ids, if you are using Oracle this won't work. You would need to use SEQUENCE.
       private Long id;
    
       @ManyToOne
       @JoinColumn(name = "group_id") //There will be no need to specify the join column if you use group_id.
       private Group group;
    
       @Column(name = "name")
       private String name;
    
       ...
       // getters and setters....   
    }
    
    @Entity
    @Table(name = "groups")
    public class Group {
    
       @Id
       @GeneratedValue(strategy = GenerationType.IDENTITY)
       private Long id;
    
       @Column(name="group_name")
       private String groupName;
    
       ...
       // getters and setters....   
    }
    

    如果可以的话,我会将表格的名称更改为复数。

    我还使用了一些对我有很大帮助的东西。我有一个名为“Identifiable”的超类,它只有 id,它看起来像这样:

    @MappedSuperclass
    public class Identifiable implements Serializable {
    
        private static final long serialVersionUID = -9027542469937539859L;
    
        @Id
        @Column(name = "ID")
        @GeneratedValue
        private Long id;
    
        public Long getId() {
            return id;
        }
    
        public void setId(Long id) {
            this.id = id;
        }
    
        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + ((id == null) ? 0 : id.hashCode());
            return result;
        }
    
        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            Identifiable other = (Identifiable) obj;
            if (id == null) {
                return false;
            } else if (!id.equals(other.id))
                return false;
            return true;
        }
    
    }
    

    这样您就可以轻松地使用 id 扩展所有类,例如:

    @Entity
    @Table(name = "users")
    public class User extends Identifiable {
    
       private static final long serialVersionUID = -90275424699375956859L;
    
       @ManyToOne
       @JoinColumn(name = "group_id") //There will be no need to specify the join column if you use group_id.
       private Group group;
    
       @Column(name = "name")
       private String name;
    
       ...
       // getters and setters....   
    }
    

    但是,如果您无法更改名称,请告诉我们您遇到的跟踪问题,我们或许可以提供帮助。

    谢谢!

    【讨论】:

      猜你喜欢
      • 2015-08-08
      • 2012-12-31
      • 1970-01-01
      • 1970-01-01
      • 2016-11-22
      • 2020-02-20
      • 2012-11-30
      • 2011-01-22
      • 1970-01-01
      相关资源
      最近更新 更多