这个问题与我昨天问的上一个问题相关。 我在 Employee 和 SkillSet 表之间有多对多关系,每个关系都有附加列 numberOfYears
employeeId skillSetId numberOfYears
10 101 2
由于 EmployeeSkillSet 表中没有 ID 列,因此我使用
@IdClass
来定义复合键
@Entity
class Employee {
private @Id Long id;
@OneToMany(mappedBy="employeeId")
private List<EmployeeSkillSet> skillSets;
}
class SkillSet {
private @Id Long id;
}
@IdClass(EmpSkillKey.class)
@Entity
class EmployeeSkillSet {
@Id
@Column("employee_id")
private Long employeeId;
@Id
@Column("skill_id")
private @Id Long skillId;
@ManyToOne
private Employee employee;
private int numberOfYears;
}
class EmpSkillKey{
private int employeeId;
private int skillId;
}
interface EmployeeRepository extends JPARepository{
List<Employee> getEmployeesBySkillSetSkillId(long id);
}
上面的 JPA 存储库方法运行良好,并根据技能集 ID 为我提供了员工列表。但是,当我尝试迭代列表并获取 EmployeeSkillSet 对象时,它会抛出错误,因为它尝试映射到错误的列
employee
而不是 employeeId
。
List<Employee> emps = employeeRepository.getEmployeesBySkillSetSkillId(101);
for(Employee e: emps){ // this line throws error
EmployeeSkillSet ess = e.getEmployeeSkillSet();
int n = ess.getNumberOfYears();
}
生成的查询是这样的。 (我已将其转换为员工用例,无法分享实际查询)
select ud.employee_id , ud.employee_id , ud.employee , ud.employee_value , rd.employee_id
from employee_skill_set ud left outer join employee rd
on ud.employee=rd.employee_id
where ud.employee_id=?
异常
WARN - SqlExceptionHelper - SQL Error: 207, SQLState: ZZZZZ
ERROR - SqlExceptionHelper - Invalid column name 'employee'.
org.hibernate.exception.GenericJDBCException: could not extract ResultSet
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:54)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:126)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:112)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:91)
at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.getResultSet(AbstractLoadPlanBasedLoader.java:449)
at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeQueryStatement(AbstractLoadPlanBasedLoader.java:202)
at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:137)
at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:102)
at org.hibernate.loader.collection.plan.AbstractLoadPlanBasedCollectionInitializer.initialize(AbstractLoadPlanBasedCollectionInitializer.java:100)
at org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:693)
at org.hibernate.event.internal.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:92)
at org.hibernate.internal.SessionImpl.initializeCollection(SessionImpl.java:1933)
at org.hibernate.collection.internal.AbstractPersistentCollection$4.doWork(AbstractPersistentCollection.java:559)
at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:261)
at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:555)
at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:143)
at org.hibernate.collection.internal.PersistentBag.iterator(PersistentBag.java:294)
可能我无法在同一类中定义
@Id employeeId
和@ManyToOne employee
。但那如何解决这个问题呢?
没关系,我找到了解决方案。用
@ManyToOne
和实际列名称注释了 @JoinColumn
关系。不知道为什么它要求将 updatable
和 insertable
制作为 false
。
@IdClass(EmpSkillKey.class)
@Entity
class EmployeeSkillSet {
@Id
@Column("employee_id")
private Long employeeId;
@Id
@Column("skill_id")
private @Id Long skillId;
@JoinColumn(name="employee_id", insertable=false, updatable=false)
@ManyToOne
private Employee employee;
private int numberOfYears;
}