一对多映射对象的休眠投影

时间:2020-06-14 12:17:45

标签: java hibernate jpa hibernate-criteria nhibernate-projections

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

我还希望仅获取具有一组权限的用户的几个字段。我的代码是

RestTemplate Class

Permission.java

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

//setter - getter methods

}

投影代码:

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();

任何想法,如何解决此问题?

1 个答案:

答案 0 :(得分:0)

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

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

Blaze-Persitence是JPA之上的查询构建器,它支持JPA模型之上的许多高级DBMS功能。我在其顶部创建了实体视图,以允许在JPA模型和自定义接口定义的模型之间轻松映射,例如类固醇上的Spring Data Projections。这个想法是您以自己喜欢的方式定义目标结构,并通过JPQL表达式将属性(获取器)映射到实体模型。由于属性名称用作默认映射,因此大多数情况下您不需要显式映射,因为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

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