下面列出了怎么用javax.persistence.Subgraph的API类实例代码及写法,或者点击链接到github查看源代码。
private void queryJoin(CriteriaBuilder cb, CriteriaQuery query, From from, FilterPath path, EntityGraph<?> eg, Subgraph sg, List<Predicate> predicates) {
String joinAttr = path.getJoinAttr();
From joinPath = null;
if (".".equals(joinAttr)) {
joinPath = from;
} else {
if (sg == null) {
sg = eg.addSubgraph(path.getJoinAttr());
} else {
sg = sg.addSubgraph(path.getJoinAttr());
}
joinPath = from.join(path.getJoinAttr());
}
applyFilter(cb, query, path.getFilters(), joinPath, predicates);
if (path.getJoinChildren() != null && path.getJoinChildren().size() > 0) {
for (FilterPath fp : path.getJoinChildren()) {
queryJoin(cb, query, joinPath, fp, eg, sg, predicates);
}
}
}
/**
* I'm using the NULL-OBJECT pattern here.
* For attributes that don't exist in the EntityGraph,
* a predefined NULL-ATTRIBUTE-NODE is pushed to the stack.
*
* And for a nonexistent subgraph, a predefined NULL-SUBGRAPH is pushed to the stack.
*
* So, whenever we start visiting an attribute, there will be an attribute node pushed to the attribute stack,
* and a subgraph node pushed to the graph stack.
*
* when we finish visiting an attribute, these two will be popped from each stack.
*/
@Override
public boolean startingAttribute(AttributeDefinition attributeDefinition) {
Map<String, AttributeNodeImplementor> attributeMap = attributeMapStack.peekLast();
final String attrName = attributeDefinition.getName();
AttributeNodeImplementor attributeNode = NON_EXIST_ATTRIBUTE_NODE;
GraphNodeImplementor subGraphNode = NON_EXIST_SUBGRAPH_NODE;
//the attribute is in the EntityGraph, so, let's continue
if ( attributeMap.containsKey( attrName ) ) {
attributeNode = attributeMap.get( attrName );
//here we need to check if there is a subgraph (or sub key graph if it is an indexed attribute )
Map<Class, Subgraph> subGraphs = attributeNode.getSubgraphs();
Class javaType = attributeDefinition.getType().getReturnedClass();
if ( !subGraphs.isEmpty() && subGraphs.containsKey( javaType ) ) {
subGraphNode = (GraphNodeImplementor) subGraphs.get( javaType );
}
}
attributeStack.addLast( attributeNode );
graphStack.addLast( subGraphNode );
return super.startingAttribute( attributeDefinition );
}
private <T> Subgraph<Object> applyFetchPaths(EntityGraph<T> graph, MetaAttributePath fetchPath) {
if (fetchPath.length() >= 2) {
// ensure parent is fetched
MetaAttributePath parentPath = fetchPath.subPath(0, fetchPath.length() - 1);
Subgraph<Object> parentGraph = applyFetchPaths(graph, parentPath);
return parentGraph.addSubgraph(fetchPath.getLast().getName());
} else {
return graph.addSubgraph(fetchPath.toString());
}
}
@Override
public void startingCollectionElements(
final CollectionElementDefinition elementDefinition) {
AttributeNodeImplementor attributeNode = attributeStack.peekLast();
GraphNodeImplementor subGraphNode = NON_EXIST_SUBGRAPH_NODE;
Map<Class, Subgraph> subGraphs = attributeNode.getSubgraphs();
Class javaType = elementDefinition.getType().getReturnedClass();
if ( !subGraphs.isEmpty() && subGraphs.containsKey( javaType ) ) {
subGraphNode = (GraphNodeImplementor) subGraphs.get( javaType );
}
graphStack.addLast( subGraphNode );
super.startingCollectionElements( elementDefinition );
}
@Override
public void startingCollectionIndex(final CollectionIndexDefinition indexDefinition) {
AttributeNodeImplementor attributeNode = attributeStack.peekLast();
GraphNodeImplementor subGraphNode = NON_EXIST_SUBGRAPH_NODE;
Map<Class, Subgraph> subGraphs = attributeNode.getKeySubgraphs();
Class javaType = indexDefinition.getType().getReturnedClass();
if ( !subGraphs.isEmpty() && subGraphs.containsKey( javaType ) ) {
subGraphNode = (GraphNodeImplementor) subGraphs.get( javaType );
}
graphStack.addLast( subGraphNode );
super.startingCollectionIndex( indexDefinition );
}
/**
* Intended only for use from {@link #makeImmutableCopy()}
*/
private AttributeNodeImpl(
SessionFactoryImplementor sessionFactory,
ManagedType managedType,
Attribute<?, T> attribute,
Map<Class, Subgraph> subgraphMap,
Map<Class, Subgraph> keySubgraphMap) {
this.sessionFactory = sessionFactory;
this.managedType = managedType;
this.attribute = attribute;
this.subgraphMap = subgraphMap;
this.keySubgraphMap = keySubgraphMap;
}
private static Map<Class, Subgraph> makeSafeMapCopy(Map<Class, Subgraph> subgraphMap) {
if ( subgraphMap == null ) {
return null;
}
final int properSize = CollectionHelper.determineProperSizing( subgraphMap );
final HashMap<Class,Subgraph> copy = new HashMap<>( properSize );
for ( Map.Entry<Class, Subgraph> subgraphEntry : subgraphMap.entrySet() ) {
copy.put(
subgraphEntry.getKey(),
( ( SubgraphImpl ) subgraphEntry.getValue() ).makeImmutableCopy()
);
}
return copy;
}
public Map<String, List<String>> getPermissionsByRealm(User user) {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Assignment> assignmentCriteria = cb.createQuery(Assignment.class);
Root<Assignment> assignmentRoot = assignmentCriteria.from(Assignment.class);
Join<Group, Assignment> groupJoin = assignmentRoot.join("group");
Join<User, Group> userJoin = groupJoin.join("users");
assignmentRoot.fetch("role").fetch("permissions");
assignmentCriteria.where(cb.equal(userJoin.get("id"), user.getId()));
EntityGraph<Assignment> assignmentGraph = em.createEntityGraph(Assignment.class);
assignmentGraph.addAttributeNodes("realm", "role");
Subgraph<Role> roleGraph = assignmentGraph.addSubgraph("role");
roleGraph.addAttributeNodes("permissions");
Subgraph<Permission> permissionsGraph = roleGraph.addSubgraph("permissions");
permissionsGraph.addAttributeNodes("name");
return em.createQuery(assignmentCriteria)
.setHint("javax.persistence.cache.storeMode", CacheStoreMode.REFRESH)
.setHint("javax.persistence.fetchgraph", assignmentGraph)
.getResultStream()
.collect(Collectors.groupingBy(Assignment::getRealm))
.entrySet()
.stream()
.collect(Collectors.toMap(
e -> e.getKey().getId().toString(),
e -> new ArrayList<>(e.getValue().stream()
.flatMap(v -> v.getRole().getPermissions().stream())
.map(Permission::getName)
.collect(Collectors.toSet()))));
}
private Subgraph<Object> applyFetchPaths(EntityGraph<T> graph, MetaAttributePath fetchPath) {
if (fetchPath.length() >= 2) {
// ensure parent is fetched
MetaAttributePath parentPath = fetchPath.subPath(0, fetchPath.length() - 1);
Subgraph<Object> parentGraph = applyFetchPaths(graph, parentPath);
return parentGraph.addSubgraph(fetchPath.toString());
}
else {
return graph.addSubgraph(fetchPath.toString());
}
}
@Override
public Map<Class, Subgraph> getSubgraphs() {
return Collections.emptyMap();
}
@Override
public Map<Class, Subgraph> getKeySubgraphs() {
return Collections.emptyMap();
}
@Override
public Map<Class, Subgraph> getSubgraphs() {
return subgraphMap == null ? Collections.emptyMap() : subgraphMap;
}
@Override
public Map<Class, Subgraph> getKeySubgraphs() {
return keySubgraphMap == null ? Collections.emptyMap() : keySubgraphMap;
}
@Override
public <X> Subgraph<? extends X> addSubclassSubgraph(Class<? extends X> type) {
// todo : implement
throw new NotYetImplementedException();
}
@Decision(HANDLE_OK)
public List<Application> handleOk(ApplicationSearchParams params, UserPermissionPrincipal principal, EntityManager em) {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Application> query = cb.createQuery(Application.class);
Root<Application> applicationRoot = query.from(Application.class);
query.distinct(true);
List<Predicate> predicates = new ArrayList<>();
if (!principal.hasPermission("any_application:read")) {
Join<User, Group> userJoin = applicationRoot.join("realms")
.join("assignments")
.join("group")
.join("users");
predicates.add(cb.equal(userJoin.get("id"), principal.getId()));
}
Optional.ofNullable(params.getQ())
.ifPresent(q -> {
String likeExpr = "%" + q.replaceAll("%", "_%") + "%";
predicates.add(cb.like(applicationRoot.get("name"), likeExpr, '_'));
});
if (!predicates.isEmpty()) {
query.where(predicates.toArray(Predicate[]::new));
}
List<ResourceField> embedEntities = some(params.getEmbed(), embed -> new ResourceFilter().parse(embed))
.orElse(Collections.emptyList());
EntityGraph<Application> applicationGraph = em.createEntityGraph(Application.class);
applicationGraph.addAttributeNodes("name", "description", "passTo", "virtualPath", "topPage", "writeProtected");
if (embedEntities.stream().anyMatch(r -> r.getName().equalsIgnoreCase("realms"))) {
applicationGraph.addAttributeNodes("realms");
Subgraph<Realm> realmsGraph = applicationGraph.addSubgraph("realms");
realmsGraph.addAttributeNodes("name", "description", "url");
}
return em.createQuery(query)
.setHint("javax.persistence.fetchgraph", applicationGraph)
.setFirstResult(params.getOffset())
.setMaxResults(params.getLimit())
.getResultList();
}
@Decision(EXISTS)
public boolean exists(Parameters params, RestContext context, EntityManager em) {
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<User> query = builder.createQuery(User.class);
Root<User> userRoot = query.from(User.class);
userRoot.fetch("userProfileValues", JoinType.LEFT);
query.where(builder.equal(userRoot.get("account"), params.get("account")));
List<ResourceField> embedEntities = some(params.get("embed"), embed -> new ResourceFilter().parse(embed))
.orElse(Collections.emptyList());
EntityGraph<User> userGraph = em.createEntityGraph(User.class);
userGraph.addAttributeNodes("account", "userProfileValues");
if (embedEntities.stream().anyMatch(r -> r.getName().equalsIgnoreCase("groups"))) {
userRoot.fetch("groups", JoinType.LEFT);
query.distinct(true);
userGraph.addAttributeNodes("groups");
userGraph.addSubgraph("groups")
.addAttributeNodes("name", "description");
}
// OIDC provider
if (embedEntities.stream().anyMatch(r -> r.getName().equalsIgnoreCase("oidc_providers"))) {
userRoot.fetch("oidcUsers", JoinType.LEFT);
userGraph.addAttributeNodes("oidcUsers");
Subgraph<Object> oidcUsersGraph = userGraph.addSubgraph("oidcUsers");
oidcUsersGraph.addSubgraph("oidcProvider")
.addAttributeNodes("name");
}
User user = em.createQuery(query)
.setHint("javax.persistence.cache.storeMode", CacheStoreMode.REFRESH)
.setHint("javax.persistence.fetchgraph", userGraph)
.getResultStream().findAny().orElse(null);
if (user != null) {
final UserProfileService userProfileService = new UserProfileService(em);
final List<UserProfileVerification> userProfileVerifications = userProfileService.findUserProfileVerifications(user.getAccount());
user.setUnverifiedProfiles(userProfileVerifications.stream()
.map(UserProfileVerification::getUserProfileField)
.filter(Objects::nonNull)
.map(UserProfileField::getJsonName)
.collect(Collectors.toList()));
context.putValue(user);
}
return user != null;
}