问题
I have a small issue. Let’s assume I have this Entity:
import lombok.Data;
import javax.persistence.*;
import java.util.Set;
@Data
@Entity
public class Person {
enum SEX {F, M}
@Id
@GeneratedValue
private Long id;
@OrderBy
@Enumerated(EnumType.STRING)
@ElementCollection(fetch = FetchType.EAGER)
private Set<SEX> sexes;
private String firstName;
private String lastName;
}
Because at some points I do not want to load the first and last name, I use Projections (https://docs.spring.io/spring-data/jpa/docs/1.10.2.RELEASE/reference/html/#projections): I define this Interface:
import java.util.Set;
public interface PersonSlim {
String getId();
Set<Person.SEX> getSexes();
}
Now have a look at this Repository:
import org.springframework.data.repository.CrudRepository;
import java.util.List;
public interface PersonRepo extends CrudRepository<Person, Long> {
List<PersonSlim> getAllBy();
}
If you enable the SQL-logging (logging.level.org.hibernate.SQL: DEBUG
) and execute the call personRepo.getAllBy();
you will see:
2018-12-14 16:36:36.808 DEBUG 14227 --- [ main] org.hibernate.SQL : select person0_.id as id1_0_, person0_.first_name as first_na2_0_, person0_.last_name as last_nam3_0_ from person person0_
So basically, Spring loads all fields. If you exclude the getSexes()
Method in the PersonSlim Interface Spring will only load the id:
2018-12-14 16:38:03.977 DEBUG 14382 --- [ main] org.hibernate.SQL : select person0_.id as col_0_0_ from person person0_
Spring loads all Fields, if my projection contains an ElementCollection.
Why is that a Problem?
I use a PostGIS-DB with geometry Fields and the geometries can be very large. So, if I load many Entities it becomes slow. At some situations I do not want to load this fields.
回答1:
It seems that when the projection contains non-primitive types, all columns will be included in the query.
There is already an issue here https://jira.spring.io/browse/DATAJPA-1218 , and it sounds from the issue that this can't be solved with projections for now.
This can be useful for you https://github.com/Blazebit/blaze-persistence , documented here Entity Views
It uses similar implementation to projections.
回答2:
In contexts like this, I would elect to create a separate entity which contained all of the fields that I cared about as opposed to relying on projections, since there is no tacit guarantee that a projected object would be returning only the fields you want in the projection.
I believe that it is adding a layer of abstraction over the actual object itself in that it will likely retrieve all of the columns, but only expose a handful.
Given that the entity drives the query for the most part, creating a separate entity to only pull back the columns you want would probably be the most expedient way to go about doing this. This would also steer you away from the temptation of casting to Person
when you wanted to use the fully hydrated entity in one or two places.
来源:https://stackoverflow.com/questions/53783016/spring-data-projection-loads-additional-fields