java - JPA 命名查询中的多对一关系

标签 java mysql jpa named-query

我是 JPA 新手,现在正在研究如何通过 manytoone 关系连接两个表。我得到的实体来自数据库。我有两个表,名为“部门”和“员工”。许多员工属于一个部门。

部门

@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)

最佳答案

应该是

@OneToMany(mappedBy = "department")
    private Collection<Employee> employeeCollection;

mappedBy = "department" 属性指定 Employee 中的 private Department Department; 字段拥有 关系(即包含查询的外键 查找某个部门的所有员工。

在这里您可以找到类似的example

关于java - JPA 命名查询中的多对一关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41755623/

相关文章:

php - 处理多个地点 ID 技巧

java - 如何使用 JPA 将 Servlet 中的 BLOB 存储在数据库中

Hibernate OneToMany JoinColmuns 和常量值

java - OpenShift:Wildfly占用了1G大部分空间,怎么办?

java - 让JFrame显示其他JFrame而不打开新窗口

Java SE 11.0.5 (LTS) 许可证(下载最新的 openJDK 更新)

mysql - InnoDB 字段类型大小与文件大小差异?

java - Hackerrank Java Map问题超时问题

mysql - MySQL 中替换字符串的问题

maven - Entitymanager 查询总是在 JEE webapp 上使用 JPA 返回一个空列表