0

我有一个USER对象,它有许多字段与PERMISSION对象具有一对多映射。

我也想只获取具有一组权限的用户的少数字段。我的代码是

public class USER {
private Integer id;
private String username;
...
...
...
private Set<Permission> permissions = new HashSet<Permission>();

//setter - getter methods

}

权限.java

public class Permission {
private String name;
private Integer id;

//setter - getter methods
}

投影代码:

Criteria criteria = session.createCriteria(User.class);
criteria.setCacheable(true);

criteria.add(eq("username", username).ignoreCase());

criteria.createAlias("permissions ", "perm", LEFT_OUTER_JOIN);

ProjectionList projectedFields = Projections.projectionList();
projectedFields.add(Projections.property("id").as("id"));
projectedFields.add(Projections.property("perm.id").as("permissions.id"));

criteria.setProjection(projectedFields);
criteria.setResultTransformer(new AliasToBeanNestedResultTransformer((User.class)));

User user = (User) criteria.uniqueResult();

我收到以下异常:

org.hibernate.PropertyNotFoundException: Could not find setter for id on interface java.util.Set
    at org.hibernate.property.ChainedPropertyAccessor.getSetter(ChainedPropertyAccessor.java:66)
    at org.hibernate.transform.AliasToBeanResultTransformer.initialize(AliasToBeanResultTransformer.java:121)
    at org.hibernate.transform.AliasToBeanResultTransformer.transformTuple(AliasToBeanResultTransformer.java:84)
    at ae.gov.adm.saeed.util.AliasToBeanNestedResultTransformer.transformTuple(AliasToBeanNestedResultTransformer.java:80)
    at org.hibernate.transform.CacheableResultTransformer.retransformResults(CacheableResultTransformer.java:230)

任何想法,如何解决这个问题?

4

1 回答 1

0

这行不通。这仅适用于标量结果,但不适用于嵌套结构。您必须自己构建对象图。

无论如何,这是Blaze-Persistence Entity Views的完美用例。

Blaze-Persitence 是一个基于 JPA 的查询构建器,它支持 JPA 模型之上的许多高级 DBMS 功能。我在它之上创建了实体视图,以允许在 JPA 模型和自定义接口定义模型之间轻松映射,例如 Spring Data Projections on steroids。这个想法是您以您喜欢的方式定义目标结构,并通过 JPQL 表达式将属性(getter)映射到实体模型。由于属性名称用作默认映射,因此您通常不需要显式映射,因为 80% 的用例是拥有作为实体模型子集的 DTO。

您的模型的映射可能看起来很简单,如下所示

@EntityView(User.class)
interface ApplicationUser {
    Integer getId();
    @Mapping("permissions.id")
    Set<Integer> getPermission();
}

查询是将实体视图应用于查询的问题,最简单的就是通过 id 进行查询。

ApplicationUser dto = entityViewManager.find(entityManager, ApplicationUser.class, id);

但是 Spring Data 集成允许您几乎像 Spring Data Projections 一样使用它:https ://persistence.blazebit.com/documentation/entity-view/manual/en_US/index.html#spring-data-features

它只会获取您告诉它获取的映射

于 2020-06-14T17:00:09.823 回答