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() 和自定义查询产生相同的结果。
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() 和自定义查询产生相同的结果。