我有一家代理机构和积压的业务。一个代理商有一个积压。
我有一个查询,可以检索所有代理,但是在尝试访问所检索代理的积压订单时得到了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是因为backlog
在null
中是agency.getBacklog().getId()
如果您看一下数据库和表backlog
,我想您会看到agency_id
是null
。因此,不能将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
。