【问题标题】:Getting entity list with ids on Hibernate 5.3在 Hibernate 5.3 上获取带有 id 的实体列表
【发布时间】:2019-03-08 05:54:55
【问题描述】:

我刚开始使用 Hibernate,我正在使用它来使用 Jersey 构建一个 RESTful API。

为了习惯 Hibernate,我正在尝试为这个实体实现 CRUD 操作(为方便起见,我排除了 getter、setter 和注释):

public class People  implements java.io.Serializable {

 private Integer id;
 private String name;
 private String surname;
 private String phone;
 private String email;
 private String dui;
 private String address;
 private Boolean state;
 private Set userses = new HashSet(0);

 public People() {
 }


 public People(String name, String surname, String phone, String email, String dui, String address) {
    this.name = name;
    this.surname = surname;
    this.phone = phone;
    this.email = email;
    this.dui = dui;
    this.address = address;
 }
 public People(String name, String surname, String phone, String email, String dui, String address, Boolean state, Set userses) {
   this.name = name;
   this.surname = surname;
   this.phone = phone;
   this.email = email;
   this.dui = dui;
   this.address = address;
   this.state = state;
   this.userses = userses;
 }

}

由于我想获取该实体的记录列表而不是其子实体(在这种情况下是用户 [是的,我知道该字段有一个有趣的名称]),因此我使用实体的构造函数获取列表:

  SessionFactory sesFact = HibernateUtil.getSessionFactory();
  Session ses = sesFact.openSession();
  Transaction tra = null;
  tra = ses.beginTransaction();
  String queryString = "SELECT new People(p.name, p.surname, p.phone, p.email, p.dui, p.address) FROM People p";
  Query query = ses.createQuery(queryString, People.class);
  List<People> people = query.list();

这种方法的问题是我得到的实体列表没有它们各自的 ID,我需要将它们放在返回列表中(...除非 Hibernate 有特定的理由不这样做,我是不知道。如果有这样的事情,如果你指出这一点,我将不胜感激。

那么,实现这一目标的最佳方法是什么?

我看到 Hibernate 生成的构造函数都没有将 id 作为参数。有什么原因吗?

我可以创建一个包含 id 作为参数的自定义构造函数,但我真的不想更改生成的 POJO,因为我的数据库很可能会更改,而且我不想丢失所有硬编码如果我自动重新生成 POJO 的东西。

【问题讨论】:

    标签: java hibernate jpa


    【解决方案1】:

    显然,我自己想出了一个解决方案。

    在尝试不同的方法时,大多数时候我都以 LazyInitializationException 告终。我一直将问题归咎于 Hibernate,因为我认为它在运行查询后立即触发了异常。但是,我没有意识到当 Jersey 尝试将实体序列化为 JSON 时触发了关系的加载,因此由于关系被延迟加载而引发异常。所以问题是泽西而不是休眠。由于我不习惯 Hibernate,导致一系列有趣的混乱。

    最后,我采用的方法是使用“标准”HQL 形式的检索列表,它返回实体及其所有字段(包括 id),然后取消之前获取的列表中每个实体的关系将其返回到 Jersey Servlet:

    tra = ses.beginTransaction();
    String queryString = "FROM People";
    Query query = ses.createQuery(queryString, People.class);
    List<People> people = query.list();
    
    for (People p : people) {
        p.setUserses(null);
    }
    
    return people;
    

    因此,我得到了没有孩子关系的人的列表。

    但是,我不完全确定这是否是最好的方法,因为如果我将它应用于需要加入各种实体的情况,我最终会得到很多嵌套的 foreach用于消除每个相关实体的不想要的关系。

    【讨论】:

      【解决方案2】:

      如果你把你的实体变成 DTO 不是更好吗?如果您不想从父母那里获取映射列表。

      类似的东西

      `

      public class PeopleDTO {
      
       private Integer id;
       private String name;
       private String surname;
       private String phone;
       private String email;
       private String dui;
       private String address;
       private Boolean state;
      
       public PeopleDTO() {
       }
      
      
       public PeopleDTO(String name, String surname, String phone, String email, String dui, String address) {
          this.name = name;
          this.surname = surname;
          this.phone = phone;
          this.email = email;
          this.dui = dui;
          this.address = address;
       }
      

      `

      String queryString = "SELECT new PeopleDTO(p.name, p.surname, p.phone, p.email, p.dui, p.address) FROM People p";

      【讨论】:

      • 我想这对于问题中显示的情况来说是一种更好的方法,其中只获取一个实体。但是,在我还需要获取一些关系的情况下(例如,如果我想要人员及其各自用户的列表),调用具有所述关系的构造函数(必须是集合的实例)?在这种情况下,我尝试调用实体的“完整”构造函数,但没有找到将 Set 作为参数传递给构造函数的方法。
      • 如果可以,您可以尝试添加您想要的映射Entity。查看示例SELECT new PeopleDTO(p.name, p.surname, p.phone, p.email, p.dui, p.address, u ) FROM People p JOIN p.userses u,然后将userses 添加为DTO 上的Set
      猜你喜欢
      • 2012-06-20
      • 2012-11-10
      • 1970-01-01
      • 2016-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多