问题
I need to replace the below sql query having left join on 2 tables with 2 same column types by using criteriabuilder api and I am getting following error when I run the program
org.hibernate.query.criteria.internal.BasicPathUsageException: Cannot join to attribute of basic type.
I checked couple of blogs, examples but couldn't get much help.
query that needs to be replaced:
SELECT connection_name, connection_date, connection_role, a.code, a.box FROM test.connections a LEFT JOIN test.samples b ON a.code = b.code AND a.box = UPPER(b.box) WHERE connection_name = ? AND connection_date = ? OFFSET ? LIMIT ?;
Connections entity class
@Entity
@Table(name = "connections", schema = "test")
public class Connections implements Serializable {
private static final long serialVersionUID = 3940341617988134707L;
@Id
@Column(name = "connection_name")
private String ConnectionName;
@Id
@Column(name = "connection_date")
private Date ConnectionDate;
@Id
@Column(name = "code")
private String Code;
@Id
@Column(name = "box")
private String box;
public Connections() {}
}
Samples entity class
@Entity
@Table(name = "samples", schema = "test")
public class Samples implements Serializable {
private static final long serialVersionUID = 3940341617988134707L;
@Id
@Column(name = "connection_role")
private String ConnectionRole;
@Id
@Column(name = "code")
private String Code;
@Id
@Column(name = "box")
private String box;
public Samples() {}
}
My implementation using criteria api.
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<SampleDTO> criteriaQuery = criteriaBuilder.createQuery(SampleDTO.class);
Root<Connections> root = criteriaQuery.from(Connections.class);
Join<Connections, Samples> joinCode = root.join("code", JoinType.LEFT);
Join<Connections, Samples> joinBox = root.join("box".toUpperCase(), JoinType.LEFT);
List<Predicate> criteriaList = new ArrayList<>();
Predicate firstCondition = criteriaBuilder.equal(root.get("connection_name"), connectionName);
criteriaList.add(firstCondition);
Predicate secondCondition = criteriaBuilder.equal(root.get("connection_date"), connectionDate);
criteriaList.add(secondCondition);
Timestamp sqlTimeStamp = epochToSQLTimeStamp(from);
criteriaQuery.where(criteriaBuilder.and(criteriaList.toArray(new Predicate[0])));
criteriaQuery.multiselect(root.get("connection_name"), root.get("connection_date"), root.get("connection_role"), root.get("code"), root.get("box"));
List<SampleDTO> results = entityManager.createQuery(criteriaQuery).setFirstResult(offset).setMaxResults(count).getResultList();
来源:https://stackoverflow.com/questions/60946156/left-join-on-unrelated-entities-using-criteria-api