为什么 Entitys 映射字段在提取后为 NULL,即使它是用 CascadeType.ALL 持久化的?

Why is Entitys mapped field NULL after fetch even it is persisted with CascadeType.ALL?

我有一个业务,我有代理和积压。一个机构有一个积压。

我有一个允许我检索所有代理机构的查询,但我在尝试访问检索到的代理机构的积压时遇到了 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 是因为 backlogagency.getBacklog().getId()

中是 null

如果你看一下数据库,table backlog 我想你会看到 agency_idnull。因此 Backlogs 不能附加到 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 是按照您的方式创建的。