JPA命名查询中的多对一关系
Posted
技术标签:
【中文标题】JPA命名查询中的多对一关系【英文标题】:ManyToOne Relation in JPA namedQuery 【发布时间】:2017-01-20 03:30:32 【问题描述】:我是 JPA 的新手,现在研究如何通过 manytoone
关系连接两个表。我得到的实体来自数据库。我有两个表,分别命名为 Department 和 Employee。许多员工属于一个部门。
部门
@Entity
@Table(name = "DEPARTMENT")
@XmlRootElement
@NamedQueries(
@NamedQuery(name = "Department.findAll", query = "SELECT d FROM Department d")
, @NamedQuery(name = "Department.findById", query = "SELECT d FROM Department d WHERE d.id = :id")
, @NamedQuery(name = "Department.findByName", query = "SELECT d FROM Department d WHERE d.name = :name"))
public class Department implements Serializable
private static final long serialVersionUID = 1L;
@Id
@Basic(optional = false)
@Column(name = "ID")
private Integer id;
@Column(name = "NAME")
private String name;
@OneToMany(mappedBy = "departmentId")
private Collection<Employee> employeeCollection;
public Department()
public Department(Integer id)
this.id = id;
public Integer getId()
return id;
public void setId(Integer id)
this.id = id;
public String getName()
return name;
public void setName(String name)
this.name = name;
@XmlTransient
public Collection<Employee> getEmployeeCollection()
return employeeCollection;
public void setEmployeeCollection(Collection<Employee> employeeCollection)
this.employeeCollection = employeeCollection;
@Override
public int hashCode()
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
@Override
public boolean equals(Object object)
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Department))
return false;
Department other = (Department) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id)))
return false;
return true;
@Override
public String toString()
return "entity.Department[ id=" + id + " ]";
员工
@Entity
@Table(name = "EMPLOYEE")
@XmlRootElement
@NamedQueries(
@NamedQuery(name = "Employee.findAll", query = "SELECT e FROM Employee e")
, @NamedQuery(name = "Employee.findByEid", query = "SELECT e FROM Employee e WHERE e.eid = :eid")
, @NamedQuery(name = "Employee.findByDeg", query = "SELECT e FROM Employee e WHERE e.deg = :deg")
, @NamedQuery(name = "Employee.findByEname", query = "SELECT e FROM Employee e WHERE e.ename = :ename")
, @NamedQuery(name = "Employee.findBySalary", query = "SELECT e FROM Employee e WHERE e.salary = :salary"))
public class Employee implements Serializable
private static final long serialVersionUID = 1L;
@Id
@Basic(optional = false)
@Column(name = "EID")
private Integer eid;
@Column(name = "DEG")
private String deg;
@Column(name = "ENAME")
private String ename;
// @Max(value=?) @Min(value=?)//if you know range of your decimal fields consider using these annotations to enforce field validation
@Column(name = "SALARY")
private Double salary;
@JoinColumn(name = "DEPARTMENT", referencedColumnName = "ID")
@ManyToOne
private Department department;
public Employee()
public Employee(Integer eid)
this.eid = eid;
public Integer getEid()
return eid;
public void setEid(Integer eid)
this.eid = eid;
public String getDeg()
return deg;
public void setDeg(String deg)
this.deg = deg;
public String getEname()
return ename;
public void setEname(String ename)
this.ename = ename;
public Double getSalary()
return salary;
public void setSalary(Double salary)
this.salary = salary;
public Department getDepartment()
return department;
public void setDepartment(Department department)
this.department = department;
@Override
public int hashCode()
int hash = 0;
hash += (eid != null ? eid.hashCode() : 0);
return hash;
@Override
public boolean equals(Object object)
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Employee))
return false;
Employee other = (Employee) object;
if ((this.eid == null && other.eid != null) || (this.eid != null && !this.eid.equals(other.eid)))
return false;
return true;
@Override
public String toString()
return "entity.Employee[ eid=" + eid + " ]";
多对一
public class ManyToOne
public static void main(String[] args)
EntityManagerFactory emfactory = Persistence.
createEntityManagerFactory("JoinTablePU");
EntityManager entitymanager = emfactory.
createEntityManager();
entitymanager.getTransaction().begin();
//Create Department Entity
Department department = new Department();
department.setName("Development");
//Store Department
entitymanager.persist(department);
//Create Employee1 Entity
Employee employee1 = new Employee();
employee1.setEname("Satish");
employee1.setSalary(45000.0);
employee1.setDeg("Technical Writer");
employee1.setDepartment(department);
//Create Employee2 Entity
Employee employee2 = new Employee();
employee2.setEname("Krishna");
employee2.setSalary(45000.0);
employee2.setDeg("Technical Writer");
employee2.setDepartment(department);
//Create Employee3 Entity
Employee employee3 = new Employee();
employee3.setEname("Masthanvali");
employee3.setSalary(50000.0);
employee3.setDeg("Technical Writer");
employee3.setDepartment(department);
//Store Employees
entitymanager.persist(employee1);
entitymanager.persist(employee2);
entitymanager.persist(employee3);
entitymanager.getTransaction().commit();
entitymanager.close();
emfactory.close();
错误
Exception Description: The attribute [employeeCollection] in entity class [class entity.Department] has a mappedBy value of [departmentId] which does not exist in its owning entity class [class entity.Employee]. If the owning entity class is a @MappedSuperclass, this is invalid, and your attribute should reference the correct subclass.
at org.eclipse.persistence.exceptions.PersistenceUnitLoadingException.exceptionSearchingForPersistenceResources(PersistenceUnitLoadingException.java:127)
at org.eclipse.persistence.jpa.PersistenceProvider.createEntityManagerFactoryImpl(PersistenceProvider.java:107)
at org.eclipse.persistence.jpa.PersistenceProvider.createEntityManagerFactory(PersistenceProvider.java:177)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:79)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:54)
at jointable.ManyToOne.main(ManyToOne.java:22)
【问题讨论】:
【参考方案1】:应该是
@OneToMany(mappedBy = "department")
private Collection<Employee> employeeCollection;
mappedBy = "department"
属性指定
Employee 中的 private Department department;
字段拥有
关系(即包含查询的外键
查找部门的所有员工。
在这里你可以找到类似的example
【讨论】:
【参考方案2】:mappedBy
属性用于表示双向关系中的逆字段。它标识employeeCollection
将在从数据库中检索部门实体时自动填充。
在你的情况下,它应该是mappedBy = department
查看this 链接以查找形成双向关系的员工-部门模型的准确表示及其详细描述。
【讨论】:
以上是关于JPA命名查询中的多对一关系的主要内容,如果未能解决你的问题,请参考以下文章