0

我有以下课程:

公司类别:

public class Company {
    @JoinTable(name = "company_employee", joinColumns = @JoinColumn(name = "company_id") , inverseJoinColumns = @JoinColumn(name = "employee_id") )
    @ManyToMany(fetch = FetchType.LAZY)
    private Set<Employee> employees;

    @Column(name = "score")
    private BigDecimal score;
}

和 Employee.class

public class Employee {
         @ManyToMany(fetch = FetchType.EAGER, mappedBy="employees")
         private Set<Company> companies;
}

Company 的 Score 列在数据库中始终为空,并且从未通过 dao 更新,因为还有其他表包含每个唯一对 Company-Employee 的分数。我需要 Score 的值,仅适用于我通过 id 获取 Employee 的情况,因此在这种情况下,Set 中的所有 Company 实例都应该包含 score,因此我将获得 Employee-Company 分数对,其中员工是 Employee。我有以下代码来实现这一点:

public Employee get(Long id) {
    Employee emp = (Employee) dao.find(id);
    List<Company> compList = compnanyService.getByEmpId(id);
    Set<Company> compSet = new HashSet<Company>(compList);
    emp.setCompanies(compSet);
    return emp;
}

而公司道包含方法:

public List<Company> getByEmpId(Long id) {
        final Query query = this.entityManager.createNativeQuery("select company.comp_id, ...some other fields, score.score from company join score on company.company_id=score.company_id where score.employee_id=:employee_id",
                Company.class);
        query.setParameter("employee_id", id);
        List<Company> comps = query.getResultList();
        return comps;
}

问题是,虽然在数据库中执行它不是空的,但它getByEmpId(id)给出了一个为空的ResultList位置。company.score

我怀疑有一些缓存介入,所以我尝试从本机查询中删除一些列,并且它应该在映射时调用一个异常,并显示“未找到列”(或类似)消息,但这种方法仍然提供List<Company>所有字段尽管 Hibernate 在控制台中打印出我所做的所有更改的本机查询,但在他们的位置上。我在这里做错了什么以及如何实现我的需要?谢谢你。

4

2 回答 2

1

It might be associated with first level cache, which can be out of sync when using native SQL queries. From here:

If you bypass JPA and execute DML directly on the database, either through native SQL queries, JDBC, or JPQL UPDATE or DELETE queries, then the database can be out of synch with the 1st level cache. If you had accessed objects before executing the DML, they will have the old state and not include the changes. Depending on what you are doing this may be ok, otherwise you may want to refresh the affected objects from the database.

So you can try using refresh method from EntityManager.

于 2015-12-28T14:12:04.513 回答
0

所以我最终这样做了:

通过查询在 db 中创建视图:

  1. CREATE VIEW companyscore AS select company.comp_id, score.emp_id ...some other fields, score.score from company join score on company.comp_id=score.comp_id;

  2. 创建了对应的实体 CompanyScore,复合主 ID 为 comp_id 和 emp_id,并创建了视图作为表。

  3. 将员工实体更改为:

    公共类员工{

        @OneToMany(fetch = FetchType.EAGER) 
        @JoinColumn(name = "emp_id")
         private Set<CompanyScore> companies;
    

    }

这样,我不仅让 score 字段始终保持一致,而且我可以选择一组字段来显示,因为整个 Company 类非常广泛,并且我不需要针对这个特定案例的所有字段。

于 2015-12-28T17:17:55.823 回答