In my Hibernated system, I have a class Picture that has some simple data, a list of Installations and some (huge) binary data. The list of Installations is implemented with a join table, as it's a ManyToMany relation, and it's defined on the Installation side:
@Entity
public class Picture {
@Id
private long pictureId;
private String mimeType;
@Lob
@Basic(fetch=FetchType.LAZY) // Don't load all data unless required
private b开发者_开发技巧yte[] picture;
@ManyToMany(mappedBy= "images")
private List<Installation> installations;
/** This should be used only to load partial objects through PictureDao */
public Picture(long pictureId, String mimeType, List<Installation> insts) {
this.pictureId = pictureId;
this.mimeType = mimeType;
this.installations = insts;
}
...
}
The constructor is there solely to allow partial selects.
@Entity
public class Installation {
@Id
private long id;
@ManyToMany(cascade=CascadeType.PERSIST)
@JoinTable(name="InstPicture",
joinColumns={@JoinColumn(name="installationId")},
inverseJoinColumns = {@JoinColumn(name="pictureId")})
@OrderBy("pictureDate ASC")
private List<Picture> images;
...
}
I'd like to be able to make a partial select that inlucdes the list of Installations, but not the picture data. I have tried the obvious solution:
Query q = em.createQuery("SELECT new Picture" +
"(p.pictureId, p.mimeType, p.installations) " +
" FROM Picture p WHERE p.pictureId = :id");
but it claims it cannot find the constructor. If I don't include the installations in the select, the field becomes null rather than a lazy loader for the list. I have also tried joining p.installations in, and it still can't find the constructor. Without the list of Installations, it works beautifully.
Is there a way to get a Collection into my partial select?
Thanks, -Lars
You can't use a collection-valued path-expression in a constructor expression. Quoting the JPA 1.0 specification:
4.8 SELECT Clause
The SELECT clause denotes the query result. More than one value may be returned from the SELECT clause of a query.
The SELECT clause may contain one or more of the following elements: a single range variable or identification variable that ranges over an entity abstract schema type, a single-valued path expression, an aggregate select expression, a constructor expression.
The SELECT clause has the following syntax:
select_clause ::= SELECT [DISTINCT] select_expression {, select_expression}* select_expression ::= single_valued_path_expression | aggregate_expression | identification_variable | OBJECT(identification_variable) | constructor_expression constructor_expression ::= NEW constructor_name ( constructor_item {, constructor_item}* ) constructor_item ::= single_valued_path_expression | aggregate_expression aggregate_expression ::= { AVG | MAX | MIN | SUM } ([DISTINCT] state_field_path_expression) | COUNT ([DISTINCT] identification_variable | state_field_path_expression | single_valued_association_path_expression)
JPA 2.0 gives you a bit more of power for the constructor_item (see this answer) but, still, you won't be able to pass a collection-valued path-expression.
精彩评论