来自结果集的HIbernate错误分组

时间:2017-06-05 16:27:51

标签: oracle hibernate jdbc oracle12c

我试图使用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

0 个答案:

没有答案