JPA 无法保留与 ManyToOne 外键关联的记录

JPA failed to persist record with ManyToOne foreign key association

EntityManager.find() 方法和针对 select 特定数据条目的自定义查询有何区别?

我有一个 Student 实体,它通过 SCHOOL_ID 对 School 实体具有外键约束。在保留新学生记录时,JPA 尝试将现有学校条目插入 SCHOOL table,这会导致数据库完整性异常。学校条目已通过以下代码添加到学生记录中:

student.setSchool(em.createNamedQuery("getSchoolByName", School.class).setParameter("name", schoolName).getSingleResult());

查询是

@NamedQueries({@NamedQuery(name="getSchoolByName", query="SELECT sc FROM School sc WHERE ts.name = :name")})

学校名称字段有唯一限制,因此给定名称肯定会产生单一结果。

但是如果我使用find()方法通过id(主键)检索学校记录,就没有这个问题。

student.setSchool(em.find(School.class, schoolId)); 

STUDENT 和 SCHOOL table 都以 id 作为主键。

学生实体中的外键关联class看起来像

//uni-directional many-to-one association to TestSuite
@ManyToOne(targetEntity=School.class,cascade={CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH})
@JoinColumn(name="SCHOOL_ID", referencedColumnName="SCHOOL_ID", nullable=false, insertable=false, updatable=false)
private School school;

原来是持久化上下文的问题。该查询实际上是由一个新的实体管理器发出的,它与处理持久化的实体管理器具有不同的上下文。一旦统一到一个实体管理器中,就没有更多问题了。 find() 和自定义查询产生相同的结果。