I am trying to use a projection to pull in data from an entity an some relations it has. However. The constructor on the projection takes three arguments; a set, integer and another integer. This all works fine if I don't have the set in there as an argument, but as soon as I add the set, I start getting SQL syntax query errors.
Here is an example of what I'm working with...
@Entity
public class Resource {
private Long id;
private String name;
private String path;
@ManyToOne
@JoinColumn(name = "FK_RENDITION_ID")
private Rendition rendition;
}
@Entity
public class Document {
private Long id;
private Integer pageCount;
private String code;
}
@Entity
public class Rendition {
Long id;
@ManyToOne
@JoinColumn(name="FK_DOCUMENT_ID")
Document doc;
@OneToMany(mappedBy="rendition")
Set<Resource> resources;
}
public class Projection {
@QueryProjection
public Projection(Set<Resource> resources, Integer pageCount, String code) {
}
}
Here is the query like what I am using (not exactly the same as this is a simplified version of what I'm dealing with)....
QRendition rendition = QRendition.rendition;
Projection projection = from(rendition)
.where(rendition.document().id.eq(documentId)
.and(rendition.resources.isNotEmpty())
.limit(1)
.singleResult(
new QProjection(rendition.resources,
rendition.document().pageCount,
rendition.document().code));
This query works fine as long as my projection class does not have the rendition.resources in it. If I try and add that in, I start getting malformed SQL errors (it changes the output sql so that it starts with this.
select . as col_0_0_
So, I guess my main question here is how do I include a Set as an object in a projection? Is it possible, or am I just doing something wrong here?
Using collections in projections is unreliable in JPA. It is safer to join the collection and aggregate the results instead.
Querydsl can also be used for result aggregation http://www.querydsl.com/static/querydsl/3.2.0/reference/html/ch03s02.html#d0e1799
In your case something like this
QRendition rendition = QRendition.rendition;
Projection projection = from(rendition)
.innerJoin(rendition.document, document)
.innerJoin(rendition.resources, resource)
.where(document.id.eq(documentId))
.limit(1)
.transform(
groupBy(document.id).as(
new QProjection(set(resources),
document.pageCount,
document.code)));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With