我有一家代理机构和积压的业务。一个代理商有一个积压。

我有一个查询,可以检索所有代理,但是在尝试访问所检索代理的积压订单时得到了NPE。

当我在JPA中获得一个保存的对象时,是否也应该具有相关的对象?

这是我的实体和服务:

机构

@NamedQuery(name="allAgences", query="select a from Agency a")
@Stateless
@Entity
public class Agency implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue
    private int id;

    private String name;

    @OneToOne(optional = true, orphanRemoval = true,
            cascade=CascadeType.ALL, mappedBy="agency",
            targetEntity=Backlog.class )
    private Backlog backlog;

    public Agency(String name, Backlog backlog) {
        this.name = name;
        this.backlog = backlog;
    }

    public Agency() {
        this.setName("");
        this.setBacklog(new Backlog());
    }
}
// getters, setters...


积压

@Stateless
@Entity
public class Backlog implements Serializable {

   private static final long serialVersionUID = 1L;
   Id
   @GeneratedValue
   private int id;

   @OneToOne(optional = true)
   @JoinColumn(name = "agency_id")
   private Agency agency;

   public Backlog() {}
    //getters, setters....
}


我的Ejb服务

@Stateless
@LocalBean
public class AgencyBean implements AgencyBeanRemote {

   @PersistenceContext
   private EntityManager em;

   /**
    * Default constructor.
    */
   public AgencyBean() {}

   @Override
   public Agency createAgency(String agencyName) {
      Agency agency = new Agency();
      agency.setBacklog(new Backlog());
      agency.getBacklog().setEntries(new ArrayList<>());
      agency.setName(agencyName);
      em.getTransaction().begin();
      em.persist(agency);
      em.getTransaction().commit();
      return agency;
   }

   @Override
   public List<Agency> getAllAgencies() {
      Query q = em.createNamedQuery("allAgences");
      List<Agency> agencies = q.getResultList();
      for(Agency agency : agencies) {
   //    System.out.println("hello " + agency.getBacklog().getId());
   // give me a NPE
      }
      return agencies;
   }
}

最佳答案

我想NPE是因为backlognull中是agency.getBacklog().getId()

如果您看一下数据库和表backlog,我想您会看到agency_idnull。因此,不能将Backlog附加到Agency

要解决此更改-在您的public createAgency(String agencyName)-行中

agency.setBacklog(new Backlog());




Backlog backlog = new Backlog();
agency.setBacklog(backlog);
backlog.setAgency(agency); // this should do the fix


只需提及-即如果我猜到NPE原因正确-

@OneToOne(optional = true ...
private Backlog backlog;


因此您应该期望backlog也是null,但是您没有在代码中检查它吗? (是的,我意识到这可能只是出于测试目的,仅是提及)

相关:Persist OneToOne relation

更新资料

Entity Agency中,您还可以实现以下

@PrePersist
private void prePersist() {
   // add needed NPE checks etc...
   backlog.setAgency(this);
}


这可能会减少样板代码,因为不再需要在创建backlog.setAgency(agency)的任何地方都添加此Agency

10-07 16:07