EntityManager.find()方法和用于选择特定数据条目的自定义查询之间有什么区别?
我有一个Student实体,它通过SCHOOL_ID对School实体有一个外键约束。在持久保存新学生记录时,JPA会尝试将现有学校条目插入SCHOOL表,这会导致数据库完整性异常。学校条目通过以下代码添加到学生记录中:
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表都将id作为主键。
Student实体类中的外键关联看起来像
//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;
答案 0 :(得分:1)
原来是一个持久化上下文问题。该查询实际上是由新的实体管理器完成的,该实体管理器与处理持久化的实体管理器具有不同的上下文。一旦统一到一个实体经理,就没有问题了。 find()和自定义查询产生相同的结果。