JPA getSingleResult не получил связанные объекты @OneToMany - PullRequest
0 голосов
/ 06 августа 2020

Как следует из названия, getSingleResult не извлекал связанный объект OneToMany. Но вот в чем дело, он работает после повторного развертывания проекта (это, кстати, проект JSF).

Класс аренды:

  @Id
  @Basic(optional = false)
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  @Column(name = "id")
  private Integer id;
  @Column(name = "leaseDate")
  @Temporal(TemporalType.DATE)
  private Date leaseDate;
  @Column(name = "returnDate")
  @Temporal(TemporalType.DATE)
  private Date returnDate;
  @Column(name = "status")
  private Integer status;
  
  @OneToMany(cascade = CascadeType.ALL, mappedBy = "lease")
  private Collection<LeaseDetail> leaseDetailCollection;

LeaseDetail:

  @EmbeddedId
  protected LeaseDetailPK leaseDetailPK;
  @Column(name = "status")
  private Integer status;
  @JoinColumn(name = "bookId", referencedColumnName = "id", insertable = false, updatable = false)
  @ManyToOne(optional = false)
  private Book book;
  @JoinColumn(name = "leaseId", referencedColumnName = "id", insertable = false, updatable = false)
  @ManyToOne(optional = false)
  private Lease lease;

Как Я вставляю Lease и LeaseDetail в БД:

  public Lease insert(Lease lease){
    em.persist(lease);
    return lease;
  }
  
  public void insertDetail(List<LeaseDetail> details){
    for (LeaseDetail leaseDetail : details) {
      em.persist(leaseDetail);
    }
  }

Как я получаю Lease из БД, отфильтрованной по ID:

  public Lease findLease(int id){ //THE PROBLEM: only retrieve associated LeaseDetail AFTER redeploying project
    try{
      return em.createNamedQuery("Lease.findById",Lease.class) //@NamedQuery(name = "Lease.findById", query = "SELECT l FROM Lease l WHERE l.id = :id")
          .setParameter("id", id)
          .getSingleResult();
    }catch(Exception e){
      e.printStackTrace();
      return null;
    }
  }

Если я вставляю Lease (скажем, Lease A) с несколькими связанного LeaseDetail, а затем приступить к извлечению недавно вставленной Lease (Lease A) из базы данных, у нее нет связанного LeaseDetail, хотя сама Lease полностью извлечена.

Теперь, если я повторно разверну проект, а затем перейти к получению Lease A, только тогда у него будет связанная коллекция LeaseDetail. Кажется, я не могу определить проблему.

Ответы [ 2 ]

0 голосов
/ 12 августа 2020

По умолчанию для отношения @OneToMany используется ленивая выборка. Вы можете переопределить тип выборки, добавив fetch=FetchType.EAGER в аннотацию.

@OneToMany(fetch=FetchType.EAGER) 

будьте осторожны с этим в реальном программировании, конечно, это может привести к извлечению чрезмерного количества данных из базы данных.

Если вы хотите узнать больше о ленивой выборке

https://thorben-janssen.com/5-ways-to-initialize-lazy-relations-and-when-to-use-them/

0 голосов
/ 12 августа 2020

Если вы всегда хотите получить связанную коллекцию из объекта. Вы можете использовать JOIN FETCH в @ NamedQuery.

@NamedQuery(name = "Lease.findById", query = "SELECT l FROM Lease l JOIN FETCH l.leaseDetailCollection WHERE l.id = :id")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...