1

Hiberate is creating duplicate objects as a result of my inner join. The query joins the parent table with the child table (parent has a one to many relationship with child).

Data:

Category (Parent)
ID|Name
1|A
2|B

Testcase (Child)
ID|CategoryID|Name|Run
1|1|A|500
2|1|B|500
3|1|C|500
4|2|D|600

Result from join where run = 500

CategoryID|TestcaseID|TestCase Name
1|1|A
1|2|B
1|3|C

From this, I would expect Hibernate to create one Category object with a list containing 3 testcase objects. Instead it created 3 Category objects each with the correct list of 3 testcases

Category [ID=1, name=FOO, testCases=[TestCase [ID=1, name=A, runId=500], TestCase [ID=2, name=B, runId=500], TestCase [ID=3, name=C, runId=500]]]

Category [ID=1, name=FOO, testCases=[TestCase [ID=1, name=A, runId=500], TestCase [ID=2, name=B, runId=500], TestCase [ID=3, name=C, runId=500]]]

Category [ID=1, name=FOO, testCases=[TestCase [ID=1, name=A, runId=500], TestCase [ID=2, name=B, runId=500], TestCase [ID=3, name=C, runId=500]]]

Model:

@Entity
@Table(name = "CATEGORY")
public class Category implements Serializable
{
    private static final long serialVersionUID = 1L;

    @Id
    @Column(name = "CATEGORYID")
    private int ID;

    @Column(name = "CATEGORYNAME")
    private String name;

    @OneToMany(fetch = FetchType.EAGER)
    @JoinColumn(name = "CATEGORYID")
    @Filter(name = "TEST_RUN_ID_FILTER")
    private Collection<TestCase> testCases;
}

@Entity
@Table(name = "TESTCASE_NEW")
@FilterDef(name = "TEST_RUN_ID_FILTER", defaultCondition = "TESTRUNID in (:IDS)", parameters = { @ParamDef(name = "IDS", type = "int") })
public class TestCase implements Serializable
{
    private static final long serialVersionUID = 1L;

    @Id
    @Column(name = "TESTCASEID")
    private int ID;

    @Column(name = "TESTCASENAME")
    private String name;

    @Column(name = "STATUS")
    private String status;

    @Column(name = "TESTRUNID")
    private int testRunId;
}

DAO:

 public List<Category> getAllCategoriesForTestRuns(List<Integer> testRunIDs)
    {
        Session session = getSession();
        session.enableFilter("TEST_RUN_ID_FILTER")
                .setParameterList("IDS", testRunIDs);
        Query query = session.createQuery("select c from Category c inner join c.testCases tc");
        List<Category> result = query.list();
        return result;
    }

I am able to get the right result if I chage the HQL query to select distinct, but I am wondering if there is a more correct way. From my Googling, I tried adding @Fetch(FetchMode.SELECT) to the testCase list in Category but that had no effect.

Thanks!

1 Answer 1

2

Use a ResultTransformer:

Query query = session.createQuery("hql")
                  .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

The issue is that your inner join will return an object for each entity in the testCases collection (as a DB query result set would for an inner join).

Sign up to request clarification or add additional context in comments.

1 Comment

Very helpful thanks. It does make sense when you think of it as a result set! I'd been adding each resulting object to a set to filter out duplicates which always felt wrong.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.