I am trying to build a complex query. My objects look like this:
@Entity public class Configuration{ @Id @Column(name="CONF_ID") protected Long configurationId; @ManyToMany @MapKey(name="componentType") @JoinTable(name="CONF_COMP", joinColumns={@JoinColumn(name="CONF_ID", referencedColumnName="CONF_ID")}, inverseJoinColumns={@JoinColumn(name="COMP_ID", referencedColumnName="componentId")}) protected Map<String, Component> components; }
AND
@Entity public class Component { @Id protected long componentId; @ElementCollection protected Map<String, String> properties; @ManyToMany(mappedBy="components") private List<Configuration> configurations; @Column(name="COMP_TYPE") protected String componentType; }
My problem is the correct request for the properties field. I cannot create a query to get all the configurations where component A has property Prop1 = 1 and component B has property Prop2 = 2. I tried the following without success.
Root<Configuration> conf = cq.from(Configuration.class); MapJoin<Configuration, String, Component> compJoin = conf.join(Configuration_.components, JoinType.LEFT); MapJoin<Component, String, String> propJoin = compJoin.join(Component_.properties, JoinType.LEFT); Predicate p1 = cb.and( cb.equal(mapJoin.key(), "A"), cb.equal(propJoin.key(), "Prop1"), cb.equal(propJoin.value(), "1")); Predicate p2 = cb.and( cb.equal(mapJoin.key(), "B"), cb.equal(propJoin.key(), "Prop2"), cb.equal(propJoin.value(), "2")); Predicate[] pArray = new Predicate[]{p1, p2}; cq.where(pArray); cq.select(conf).distinct(true);
EDIT: The query displayed by the registrar is as follows:
SELECT DISTINCT t2.CONF_ID, t2.DTYPE, t2.TOTALPRICE, t2.NAME FROM CONFIGURATION t2 LEFT OUTER JOIN (CONF_COMP t3 JOIN COMPONENT t1 ON (t1.COMPONENTID = t3.COMP_ID)) ON (t3.CONF_ID = t2.CONF_ID) LEFT OUTER JOIN Component_PROPERTIES t0 ON (t0.Component_COMPONENTID = t1.COMPONENTID) WHERE (((((t1.COMP_TYPE = ?) AND (t0.PROPERTIES_KEY = ?)) AND t0.PROPERTIES LIKE ?) AND (((t1.COMP_TYPE = ?) AND (t0.PROPERTIES_KEY = ?)) AND t0.PROPERTIES LIKE ?)) AND (t2.DTYPE = ?)) bind => [7 parameters bound]
I assume that he is trying to find a configuration where, possibly, all conditions apply to the SAME component? It works if I apply restrictions for only one component, but I get an empty list of results when applying 2 or more, although there are records in the database that satisfy the conditions.
UPDATE
After executing the Pimgd sentence, I got a query that looks like this:
SELECT DISTINCT t1.CONF_ID, t1.DTYPE, t1.TOTALPRICE, t1.NAME FROM CONFIGURATION t1 LEFT OUTER JOIN (CONF_COMP t2 JOIN COMPONENT t0 ON (t0.COMPONENTID = t2.COMP_ID)) ON (t2.CONF_ID = t1.CONF_ID) WHERE ((( t0.COMPONENTID IN (SELECT t3.COMPONENTID FROM COMPONENT t3 LEFT OUTER JOIN Component_PROPERTIES t4 ON (t4.Component_COMPONENTID = t3.COMPONENTID) WHERE ((t4.PROPERTIES_KEY = Brand) AND (t4.PROPERTIES = Intel)))) AND t0.COMPONENTID IN (SELECT t6.COMPONENTID FROM COMPONENT t6 LEFT OUTER JOIN Component_PROPERTIES t7 ON (t7.Component_COMPONENTID = t6.COMPONENTID) WHERE ((t7.PROPERTIES_KEY = Capacity) AND t7.PROPERTIES LIKE 4GB%))))
One criterion works, two do not give results.
Any help is much appreciated!