为什么 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 是因为 backlog
在 agency.getBacklog().getId()
中是 null
如果你看一下数据库,table backlog
我想你会看到 agency_id
是 null
。因此 Backlog
s 不能附加到 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
是按照您的方式创建的。
我有一个业务,我有代理和积压。一个机构有一个积压。
我有一个允许我检索所有代理机构的查询,但我在尝试访问检索到的代理机构的积压时遇到了 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
在 agency.getBacklog().getId()
null
如果你看一下数据库,table backlog
我想你会看到 agency_id
是 null
。因此 Backlog
s 不能附加到 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
是按照您的方式创建的。