我有以下课程:
Company.class:
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;
}
公司的分数列在数据库中始终为空,并且从不通过dao更新,因为还有其他表包含每个唯一对Company-Employee的分数。 我需要Score的值,仅适用于我通过id获取Employee的情况,因此这种情况下Set中的所有公司实例都应包含得分,因此我将获得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;
}
公司Dao包含方法:
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>
为空虽然在db中执行但它不为空。
我怀疑有一些缓存介入,所以我尝试从本机查询中删除一些列,它应该在映射时调用“没有找到列”(或相似)消息的异常,但是这种方法仍然给出了虽然Hibernate在控制台中打印出我的本机查询,并且我做了所有更改,但\[ContestPool\]
包含所有字段。
我在这里做错了什么以及如何实现我的需求?谢谢。
答案 0 :(得分:1)
它可能与第一级缓存相关联,在使用本机SQL查询时可能会不同步。来自here:
如果您绕过JPA并直接在数据库上执行DML 通过本机SQL查询,JDBC或JPQL UPDATE或DELETE查询, 那么数据库可能与第一级缓存不同步。如果你 在执行DML之前访问过对象,它们将具有旧的 状态,不包括更改。取决于你在做什么 这可能没问题,否则您可能想要刷新受影响的对象 来自数据库。
因此,您可以尝试使用refresh
中的EntityManager
方法。
答案 1 :(得分:0)
所以我最终这样做了:
从查询中创建db中的视图:
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;
创建了对应的实体CompanyScore,其复合主要ID为comp_id和emp_id,并将视图创建为表格。
将员工实体更改为:
公共类员工{
@OneToMany(fetch = FetchType.EAGER)
@JoinColumn(name = "emp_id")
private Set<CompanyScore> companies;
}
这样我不仅可以将得分字段保持一致,而且我可以选择要显示的字段集,因为整个公司类非常广泛,并且我不需要这个特定情况的所有字段。