我试图使用Hibernate检索实体及其子实体。它大部分时间都可以正常工作。但是,有时,子实体被错误地分组,这是随机发生的。让我试着解释一下。
我的实体课 -
员工(母公司):
@Entity
@Table(name="EMP")
public class Employee {
@Id
@Column(name="EMP_ID")
private String id;
@Column(name="EMP_NME")
private String empNme;
@OneToMany(mappedBy="Employee")
@Fetch(FetchMode.SUBSELECT)
private List<EmployeeRole> empRoles;
//--Getters and Setters--
@Override
public int hashCode() {
return 31 + ((this.getId() == null) ? 0 : this.getId().hashCode());
}
@Override
public boolean equals(Object obj) {
// --NUll and InstanceOf checks--
return this.getId().equals(((Employee) obj).getId());
}
}
EmployeeRole(子实体):
@Entity
@Table(name="EMP_ROLE")
public class EmployeeRole extends BaseEntity implements Serializable {
@EmbeddedId
private EmployeeRolePK id;
@Column(name="EMP_ROLE_EXPT_DT")
@Type(type = "org.jadira.usertype.dateandtime.threeten.PersistentLocalDate")
private LocalDate empRoleExptDate;
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="EMP_ID", insertable=false, updatable=false)
private Employee Employee;
//--Getters and Setters--
@Override
public int hashCode() {
return 31 + ((this.getId() == null) ? 0 : this.getId().hashCode());
}
@Override
public boolean equals(Object obj) {
// --NUll and InstanceOf checks--
return this.getId().equals(((Employee) obj).getId());
}
}
EmployeeRolePK(EmployeeRole的主键):
@Embeddable
public class EmployeeRolePK {
@Column(name="EMP_ID")
private String empId;
@Column(name="ROLE_ID")
private long roleId;
@Column(name="ROLE_TYP")
private String roleTyp;
@Column(name="EMP_ROLE_EFF_DT")
@Type(type = "org.jadira.usertype.dateandtime.threeten.PersistentLocalDate")
private LocalDate empRoleEffDate;
//--Getters and Setters--
public boolean equals(Object other) {
// --NUll and InstanceOf checks--
EmployeeRolePK castOther = (EmployeeRolePK)other;
return this.empId.equals(castOther.empId) && (this.roleId == castOther.roleId)
&& this.roleTyp.equals(castOther.roleTyp) && this.empRoleEffDate.equals(castOther.empRoleEffDate);
}
public int hashCode() {
final int prime = 31;
int hash = 17;
hash = hash * prime + this.empId.hashCode();
hash = hash * prime + ((int) (this.roleId ^ (this.roleId >>> 32)));
hash = hash * prime + this.roleTyp.hashCode();
hash = hash * prime + this.empRoleEffDate.hashCode();
return hash;
}
}
获取Employee和EmployeeRoles的标准:
Criteria criteria = this.getSession().createCriteria(Employee.class);
criteria.add(Restrictions.in("id", parameterList));
List<Employee> entities = criteria.list()
假设有3名员工E1,E2&amp; E3,他们每个人都有两个角色 -
| EMP_ID | ROLE_ID | ROLE_TYP | EMP_ROLE_EFF_DT | EMP_ROLE_EXPT_DT |
|--------|---------|----------|-----------------|------------------|
| E1 | 1111 | T1 | 2017-05-01 | <null> |
|--------|---------|----------|-----------------|------------------|
| E1 | 2222 | T2 | 2017-05-01 | <null> |
|--------|---------|----------|-----------------|------------------|
| E2 | 3333 | T1 | 2017-05-01 | <null> |
|--------|---------|----------|-----------------|------------------|
| E2 | 4444 | T2 | 2017-05-01 | <null> |
|--------|---------|----------|-----------------|------------------|
| E3 | 1111 | T1 | 2017-05-01 | <null> |
|--------|---------|----------|-----------------|------------------|
| E3 | 2222 | T2 | 2017-05-01 | <null> |
|--------|---------|----------|-----------------|------------------|
对于这个数据集,我期望E1有两个角色,E2有两个角色,E3有两个角色..这大部分时间都按预期工作..
但是,有时输出的E1有两个角色,E2没有任何角色,E3有四个角色......这是随机发生的。
我检查了hibernate.log,并在迭代结果集时看到问题。当它遍历结果集时,它会发现E3四次。不确定原因。我尝试使用dbcp跟踪日志记录,但dbcp没有记录任何内容。
以下摘录 -
2017-06-02 19:13:45,653 DEBUG ?#?:? Static select for one-to-many com.test.Employee.empRoles: select emprole0_.EMP_ID as EMP_2_49_1_, emprole0_.EMP_ROLE_EFF_DT as EMP_ROLE1_25_1_, emprole0_.EMP_ID as EMP_2_25_1_, emprole0_.ROLE_ID as ROLE_ID3_25_1_, emprole0_.ROLE_TYP as ROLE_TYP4_25_1_, emprole0_.EMP_ROLE_EFF_DT as EMP_ROLE1_25_0_, emprole0_.EMP_ID as EMP_2_25_0_, emprole0_.ROLE_ID as ROLE_ID3_25_0_, emprole0_.ROLE_TYP as ROLE_TYP4_25_0_, emprole0_.EMP_ROLE_EXPT_DT as EMP_ROLE5_25_0_ from EMP_ROLE emprole0_ where emprole0_.EMP_ID in (select this_.EMP_ID from EMP this_ where this_.EMP_ID in (?, ?, ?))
2017-06-02 19:13:45,654 TRACE ?#?:? binding parameter [1] as [VARCHAR] - E1
2017-06-02 19:13:45,654 TRACE ?#?:? binding parameter [2] as [VARCHAR] - E2
2017-06-02 19:13:45,654 TRACE ?#?:? binding parameter [3] as [VARCHAR] - E3
2017-06-02 19:13:45,666 DEBUG ?#?:? Result set row: 0
2017-06-02 19:13:45,666 TRACE ?#?:? Found [2017-05-01] as column [EMP_ROLE1_25_0_]
2017-06-02 19:13:45,666 TRACE ?#?:? Found [E1] as column [EMP_2_25_0_]
2017-06-02 19:13:45,666 TRACE ?#?:? Found [1111] as column [ROLE_ID3_25_0_]
2017-06-02 19:13:45,666 TRACE ?#?:? Found [T1] as column [ROLE_TYP4_25_0_]
2017-06-02 19:13:45,666 DEBUG ?#?:? Result set row: 1
2017-06-02 19:13:45,666 TRACE ?#?:? Found [2017-05-01] as column [EMP_ROLE1_25_0_]
2017-06-02 19:13:45,666 TRACE ?#?:? Found [E1] as column [EMP_2_25_0_]
2017-06-02 19:13:45,666 TRACE ?#?:? Found [2222] as column [ROLE_ID3_25_0_]
2017-06-02 19:13:45,666 TRACE ?#?:? Found [T2] as column [ROLE_TYP4_25_0_]
2017-06-02 19:13:45,668 TRACE ?#?:? Result set row: 2
2017-06-02 19:13:45,668 TRACE ?#?:? Found [2017-05-01] as column [EMP_ROLE1_25_0_]
2017-06-02 19:13:45,668 TRACE ?#?:? Found [E3] as column [EMP_2_25_0_]
2017-06-02 19:13:45,668 TRACE ?#?:? Found [3333] as column [ROLE_ID3_25_0_]
2017-06-02 19:13:45,668 TRACE ?#?:? Found [T1] as column [ROLE_TYP4_25_0_]
2017-06-02 19:13:45,668 TRACE ?#?:? Result set row: 3
2017-06-02 19:13:45,668 TRACE ?#?:? Found [2017-05-01] as column [EMP_ROLE1_25_0_]
2017-06-02 19:13:45,668 TRACE ?#?:? Found [E3] as column [EMP_2_25_0_]
2017-06-02 19:13:45,668 TRACE ?#?:? Found [4444] as column [ROLE_ID3_25_0_]
2017-06-02 19:13:45,668 TRACE ?#?:? Found [T2] as column [ROLE_TYP4_25_0_]
2017-06-02 19:13:45,668 TRACE ?#?:? Result set row: 4
2017-06-02 19:13:45,668 TRACE ?#?:? Found [2017-05-01] as column [EMP_ROLE1_25_0_]
2017-06-02 19:13:45,668 TRACE ?#?:? Found [E3] as column [EMP_2_25_0_]
2017-06-02 19:13:45,668 TRACE ?#?:? Found [1111] as column [ROLE_ID3_25_0_]
2017-06-02 19:13:45,668 TRACE ?#?:? Found [T1] as column [ROLE_TYP4_25_0_]
2017-06-02 19:13:45,669 DEBUG ?#?:? Result set row: 5
2017-06-02 19:13:45,669 TRACE ?#?:? Found [2017-05-01] as column [EMP_ROLE1_25_0_]
2017-06-02 19:13:45,669 TRACE ?#?:? Found [E3] as column [EMP_2_25_0_]
2017-06-02 19:13:45,669 TRACE ?#?:? Found [2222] as column [ROLE_ID3_25_0_]
2017-06-02 19:13:45,669 TRACE ?#?:? Found [T2] as column [ROLE_TYP4_25_0_]
这可能是什么原因?任何帮助深表感谢。谢谢。
版本:Hibernate 4.2.8,commons-dbcp 1.4
编辑:多次重试后,我们将问题区域缩小到JDBC驱动程序或Oracle本身。我们通过JDBC运行了hibernate生成的查询并遇到了同样的问题。我们还发现了一种重新创建此错误的模式 - 传递随机输入参数,并且第一次失败。如果再次尝试使用相同的参数,它可以正常工作。我们在SQLDeveloper中也看到过一次这个错误。
这是查询 -
select emprole0_.EMP_ID as EMP_2_49_1_, emprole0_.EMP_ROLE_EFF_DT as EMP_ROLE1_25_1_, emprole0_.EMP_ID as EMP_2_25_1_,
emprole0_.ROLE_ID as ROLE_ID3_25_1_, emprole0_.ROLE_TYP as ROLE_TYP4_25_1_,
emprole0_.EMP_ROLE_EFF_DT as EMP_ROLE1_25_0_, emprole0_.EMP_ID as EMP_2_25_0_,
emprole0_.ROLE_ID as ROLE_ID3_25_0_, emprole0_.ROLE_TYP as ROLE_TYP4_25_0_, emprole0_.EMP_ROLE_EXPT_DT as EMP_ROLE5_25_0_
from EMP_ROLE emprole0_ where emprole0_.EMP_ID in (
select this_.EMP_ID from EMP this_ where this_.EMP_ID in (?, ?, ?)
)
如果删除内部查询,则每次运行都正常。但是对于内部查询,结果有时是不正确的。我猜SQLDeveloper也使用JDBC驱动程序,所以这似乎是一个驱动程序问题。我们可能会尝试使用SQLPlus。
版本 - Oracle 12c,ojdbc7