Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

eclipselink AdditionalCriteria ignored in child class

If I setup a parent/child relationship with both parent and child having additionalcriteria constraints, and then use @JoinFetch then childs additionalcriteria are ignored.

For example:

TableA.java:

@javax.persistence.Entity
@Table(name = "TABLE_A")
@AdditionalCriteria("this.tableAfield2=:propA")
public class TableA {

    @Id
    @Column(name = "TABLEAFIELD1")
    private String tableAfield1;

    @Column(name = "TABLEAFIELD2")
    private String tableAfield2;

    @JoinColumn(name = "TABLEAFIELD2", referencedColumnName = "TABLEBFIELD1", insertable = false, updatable = false)  
    @OneToOne(fetch = FetchType.EAGER)    
//    @JoinFetch(JoinFetchType.OUTER)
    private TableB tableAtableB;
}

TableB.java:

@javax.persistence.Entity
@Table(name = "TABLE_B")
@AdditionalCriteria("this.tableBfield2=:propB")
public class TableB {

    @Id
    @Column(name = "TABLEBFIELD1")
    private String tableBfield1;

    @Column(name = "TABLEBFIELD2")
    private String tableBfield2;

    public String getTableBfield1() {
        return tableBfield1;
    }

    public String getTableBfield2() {
        return tableBfield2;
    }


}

Main:

        em.setProperty("propA", "propertyAValue");
        em.setProperty("propB", "propertyBValue");
        CriteriaBuilder cb = em.getCriteriaBuilder();
        CriteriaQuery<TableA> criteriaQuery = cb.createQuery(TableA.class);
        Root<TableA> tableA = criteriaQuery.from(TableA.class);
        Predicate pred = cb.equal(tableA.get("tableAfield1"), "keyA1");
        criteriaQuery.where(pred);
        List<TableA> results = em.createQuery(criteriaQuery).getResultList();

With tableA set as per the example (with JoinFetch commented out) the applications creates 2 SQLs

SELECT TABLEAFIELD1, TABLEAFIELD2 FROM TABLE_A WHERE ((TABLEAFIELD1 = ?) AND (TABLEAFIELD2 = ?))
    bind => [keyA1, propertyAValue]

SELECT TABLEBFIELD1, TABLEBFIELD2 FROM TABLE_B WHERE ((TABLEBFIELD1 = ?) AND (TABLEBFIELD2 = ?))
    bind => [propertyAValue, propertyBValue]

which is fine, as eclipselink is loading the table_b on demand.

but for our application we need to have a single SQL, as there maybe 1000s of rows and we need a single join.

So, if I put back the @JoinFetch then the sql generated is;

SELECT t1.TABLEAFIELD1, t1.TABLEAFIELD2, t0.TABLEBFIELD1, t0.TABLEBFIELD2 FROM TABLE_A t1 LEFT OUTER JOIN TABLE_B t0 ON (t0.TABLEBFIELD1 = t1.TABLEAFIELD2) WHERE ((t1.TABLEAFIELD1 = ?) AND (t1.TABLEAFIELD2 = ?))
    bind => [keyA1, propertyAValue]

the additionalCriteria from TableB is not added (there is no t0.tableBField1=? (propertyBValue) )

Any suggestions? Its driving me mad.

Many thanks

For completeness here are the tables

create table TABLE_A (
TABLEAFIELD1 varchar2(20),
TABLEAFIELD2 varchar2(30),
CONSTRAINT tableApk PRIMARY KEY (TABLEAFIELD1)
) ;

create table TABLE_B (
TABLEBFIELD1 varchar2(20),
TABLEBFIELD2 varchar2(30),
CONSTRAINT tableBpk PRIMARY KEY (TABLEBFIELD1)
) ;

insert into TABLE_A (TABLEAFIELD1,TABLEAFIELD2) values ('keyA1','propertyAValue');
insert into TABLE_A (TABLEAFIELD1,TABLEAFIELD2) values ('keyA2','propertyAValue');
insert into TABLE_A (TABLEAFIELD1,TABLEAFIELD2) values ('keyA3','random');

insert into TABLE_B (TABLEBFIELD1,TABLEBFIELD2) values ('propertyAValue','propertyBValue');
like image 847
Ric Ambridge Avatar asked Nov 07 '22 16:11

Ric Ambridge


1 Answers

So this is a long term bug with eclipselink and doesn't look like it will be fixed.

The solution was to change

@JoinFetch(JoinFetchType.OUTER)

to

@BatchFetch(BatchFetchType.JOIN)

This doesn't exactly have the result I was hoping for, originally wanted the generated sql to include an OUTER JOIN, but BatchFetch results in only 2 SQLs, one to get the Table_A items, then another to fetch all the Table_B items (including the additionalcriteria requirements)

like image 79
Ric Ambridge Avatar answered Nov 15 '22 07:11

Ric Ambridge