为什么实体在获取后将字段映射为NULL,即使它与CascadeType.ALL持久存在?

时间:2017-11-22 21:47:08

标签: java jpa one-to-one

我有一家公司,我有代理商和积压工作。一个机构有一个积压工作。

我有一个查询,允许我检索所有代理商,但我在尝试访问所检索代理商的积压时获得了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;
   }
}

1 个答案:

答案 0 :(得分:2)

我猜NPE是因为mClusterManager.getRenderer().setOnClusterClickListener(new ClusterManager.OnClusterClickListener<MyMarker>() { @Override public boolean onClusterClick(Cluster<MyMarker> cluster) { return true; } }); 中的backlog null

如果您查看数据库和表格agency.getBacklog().getId(),我认为您看到backlogagency_id。因此null无法附加Backlog

修复此更改 - 在Agency - 行

public createAgency(String agencyName)

到行

agency.setBacklog(new Backlog());

仅举几例 - 即如果我猜到NPE原因正确 - 你有

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

所以你应该期望@OneToOne(optional = true ... private Backlog backlog; 也是backlog,但是你没有在你的代码中检查它? (是的,我意识到它可能仅用于测试目的,但仅提及)

相关:Persist OneToOne relation

<强>更新

null Entity中,您还可以实施以下内容

Agency

这可能会减少样板代码,因为不再需要在@PrePersist private void prePersist() { // add needed NPE checks etc... backlog.setAgency(this); } 处添加backlog.setAgency(agency),而是按照您的方式创建Agency