下面列出了怎么用javax.persistence.EntityGraph的API类实例代码及写法,或者点击链接到github查看源代码。
@Test
void findByNoSuchGroupId() {
CriteriaQuery query = mock(CriteriaQuery.class);
TypedQuery typedQuery = mock(TypedQuery.class);
EntityGraph graph = mock(EntityGraph.class);
Root<User> userRoot = mock(Root.class);
EntityManager em = MockFactory.createEntityManagerMock(typedQuery, graph, query, userRoot);
UsersResource resource = new UsersResource();
UserSearchParams params = builder(new UserSearchParams())
.set(UserSearchParams::setGroupId, 10L)
.build();
UserPermissionPrincipal principal = new UserPermissionPrincipal(1L, "admin", Map.of(), Set.of("any_user:read"));
resource.handleOk(params, principal, em);
verify(userRoot).join(eq("groups"));
}
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);
}
}
}
/**
* {@inheritDoc}
*/
@Override
public DocumentRouteHeaderValue getMinimalRouteHeader(String documentId) {
// This graph is defined on the DocumentRouteHeaderValue class.
EntityGraph<DocumentRouteHeaderValue> entityGraph =
(EntityGraph<DocumentRouteHeaderValue>) entityManager.createEntityGraph("DocumentRouteHeaderValue.ActionListAttributesOnly");
TypedQuery<DocumentRouteHeaderValue> query = entityManager.createQuery("SELECT rh FROM DocumentRouteHeaderValue rh WHERE rh.documentId = :documentId", DocumentRouteHeaderValue.class );
// By using the graph - all properties but those on the graph should have
// a lazy proxy in place. Attempting to access any of those *should* cause the
// rest of the properties to load.
query.setHint("javax.persistence.fetchgraph", entityGraph);
query.setParameter("documentId", documentId);
List<DocumentRouteHeaderValue> result = query.getResultList();
if ( result.isEmpty() ) {
return null;
}
return result.get(0);
}
public void init() {
log.info("call init, id @" + id);
if (id != null) {
//this.post = em.find(Post.class, this.id);
EntityGraph postEntityGraph=em.getEntityGraph("post");
// EntityGraph postEntityGraph=em.createEntityGraph(Post.class);
// postEntityGraph.addAttributeNodes("title");
// postEntityGraph.addSubgraph("comments").addAttributeNodes("content");
this.post=em
.createQuery("select p from Post p where p.id=:id", Post.class)
.setHint("javax.persistence.loadgraph", postEntityGraph)
.setParameter("id", this.id)
.getResultList()
.get(0);
PersistenceUnitUtil util=em.getEntityManagerFactory().getPersistenceUnitUtil();
log.info("title is [email protected]"+util.isLoaded(this.post, "title"));
log.info("body is [email protected]"+util.isLoaded(this.post, "body"));
log.info("comments is [email protected]"+util.isLoaded(this.post, "comments"));
} else {
throw new RuntimeException("id is required");
}
}
/**
* Fetches an instance of given PhoneBookEntry with all lazy
* loaded properties loaded.
* @param entry
* @return the fully loaded instance
*/
public PhoneBookEntry loadFully(PhoneBookEntry entry) {
// To get lazy loaded fields initialized, you have couple of options,
// all with pros and cons, 3 of them presented here.
// 1) use an explicit join query (with EntityManager or @Query annotation
// in repository method.
// em.createQuery("select e from PhoneBookEntry e LEFT JOIN FETCH e.groups where e.id = :id", PhoneBookEntry.class);
// ...
// 2) use EntityGraph's introduced in JPA 2.1, here constructed dynamically
// and passed via QueryResult object from DeltaSpike Data. You can
// also use entity graphs with @Query annotation in repositories or
// with raw EntityManager API.
EntityGraph<PhoneBookEntry> graph = this.em.createEntityGraph(
PhoneBookEntry.class);
graph.addSubgraph("groups");
entry = entryRepo.findById(entry.getId())
.hint("javax.persistence.loadgraph", graph)
.getSingleResult();
// 3) ..or use the infamous size() hack that all of us actually do :-)
entry.getAddresses().size();
return entry;
}
@SuppressWarnings("unchecked")
@Test
public void selectWithEntityGraph() {
log.info("... selectWithEntityGraph ...");
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
EntityGraph<Author> graph = em.createEntityGraph(Author.class);
graph.addAttributeNodes(Author_.books);
TypedQuery<Author> q = em.createQuery("SELECT a FROM Author a WHERE a.id = 1", Author.class);
q.setHint("javax.persistence.fetchgraph", graph);
Author a = q.getSingleResult();
em.getTransaction().commit();
em.close();
log.info(a.getFirstName()+" "+a.getLastName()+" wrote "+a.getBooks().size()+" books.");
}
@Test
public void selectWithNamedEntityGraph() {
log.info("... selectWithNamedEntityGraph ...");
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
EntityGraph<?> graph = em.createEntityGraph("graph.AuthorBooks");
TypedQuery<Author> q = em.createQuery("SELECT a FROM Author a WHERE a.id = 1", Author.class);
q.setHint("javax.persistence.fetchgraph", graph);
Author a = q.getSingleResult();
em.getTransaction().commit();
em.close();
log.info(a.getFirstName()+" "+a.getLastName()+" wrote "+a.getBooks().size()+" books.");
}
@Override
@SuppressWarnings("unchecked")
public <T> List<EntityGraph<? super T>> findEntityGraphsByType(Class<T> entityClass) {
final EntityType<T> entityType = entity( entityClass );
if ( entityType == null ) {
throw new IllegalArgumentException( "Given class is not an entity : " + entityClass.getName() );
}
final List<EntityGraph<? super T>> results = new ArrayList<>();
for ( EntityGraph entityGraph : entityGraphMap.values() ) {
if ( !EntityGraphImplementor.class.isInstance( entityGraph ) ) {
continue;
}
final EntityGraphImplementor egi = (EntityGraphImplementor) entityGraph;
if ( egi.appliesTo( entityType ) ) {
results.add( egi );
}
}
return results;
}
public Employee findByEntityGraph(int id) {
EntityGraph<Employee> entityGraph = em.createEntityGraph(Employee.class);
entityGraph.addAttributeNodes("name", "phones");
Map<String, Object> properties = new HashMap<>();
properties.put("javax.persistence.fetchgraph", entityGraph);
return em.find(Employee.class, id, properties);
}
@Override
public <T> CompletionStage<T> find(EntityGraph<T> entityGraph, Object id) {
Class<T> entityClass = ((RootGraphImplementor<T>) entityGraph).getGraphedType().getJavaType();
return delegate.reactiveFind( entityClass, id, null,
singletonMap( GraphSemantic.FETCH.getJpaHintName(), entityGraph )
);
}
protected void applyFetchPaths(Query criteriaQuery) {
EntityGraph<T> graph = em.createEntityGraph(getEntityClass());
for (MetaAttributePath fetchPath : fetchPaths) {
applyFetchPaths(graph, fetchPath);
}
criteriaQuery.setHint("javax.persistence.fetchgraph", graph);
}
@Override
public Account findAccountUsingNamedEntityGraph(Long accountId) {
EntityGraph<?> entityGraph = getEntityManager().createEntityGraph("graph.transactions");
Query query = getEntityManager().createQuery("SELECT a FROM Account AS a WHERE a.accountId=:accountId", Account.class);
query.setHint("javax.persistence.fetchgraph", entityGraph);
query.setParameter("accountId", accountId);
return (Account)query.getSingleResult();
}
@Override
public Account findAccountUsingDynamicEntityGraph(Long accountId) {
EntityGraph<?> entityGraph = getEntityManager().createEntityGraph(Account.class);
entityGraph.addSubgraph("transactions");
Map<String, Object> hints = new HashMap<String, Object>();
hints.put("javax.persistence.fetchgraph", entityGraph);
return this.getEntityManager().find(Account.class, accountId, hints);
}
@Override
public <T> void build(EntityManager em, Query criteriaQuery, Class<T> entityClass,
Set<MetaAttributePath> fetchPaths) {
EntityGraph<T> graph = em.createEntityGraph(entityClass);
for (MetaAttributePath fetchPath : fetchPaths) {
applyFetchPaths(graph, fetchPath);
}
criteriaQuery.setHint("javax.persistence.fetchgraph", graph);
}
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 <T> void addNamedEntityGraph(String graphName, EntityGraph<T> entityGraph) {
if ( entityGraph instanceof EntityGraphImplementor ) {
entityGraph = ( (EntityGraphImplementor<T>) entityGraph ).makeImmutableCopy( graphName );
}
final EntityGraph old = entityGraphMap.put( graphName, entityGraph );
if ( old != null ) {
log.debugf( "EntityGraph being replaced on EntityManagerFactory for name %s", graphName );
}
}
@Override
public <T> EntityGraph<T> createEntityGraph(final Class<T> rootType) {
final Timer timer = Op.createEntityGraph.start(this.timer, this);
try {
return getEntityManager().createEntityGraph(rootType);
} finally {
timer.stop();
}
}
public EntityGraphQueryHint(String hintName, EntityGraph<?> originEntityGraph) {
assert hintName != null;
assert HINT_FETCHGRAPH.equals( hintName ) || HINT_LOADGRAPH.equals( hintName );
this.hintName = hintName;
this.originEntityGraph = originEntityGraph;
}
@Override
public EntityGraph<?> createEntityGraph(String graphName) {
checkOpen();
final EntityGraph named = getEntityManagerFactory().findEntityGraphByName( graphName );
if ( named == null ) {
return null;
}
if ( EntityGraphImplementor.class.isInstance( named ) ) {
return ( (EntityGraphImplementor) named ).makeMutableCopy();
}
else {
return named;
}
}
@Override
public EntityGraph<?> createEntityGraph(final String graphName) {
final Timer timer = Op.createEntityGraph.start(this.timer, this);
try {
return getEntityManager().createEntityGraph(graphName);
} finally {
timer.stop();
}
}
@Decision(HANDLE_OK)
public List<Group> handleOk(GroupSearchParams params, UserPermissionPrincipal principal, EntityManager em) {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Group> query = cb.createQuery(Group.class);
Root<Group> groupRoot = query.from(Group.class);
query.distinct(true);
query.orderBy(cb.asc(groupRoot.get("id")));
List<ResourceField> embedEntities = some(params.getEmbed(), embed -> new ResourceFilter().parse(embed))
.orElse(Collections.emptyList());
EntityGraph<Group> groupGraph = em.createEntityGraph(Group.class);
groupGraph.addAttributeNodes("name", "description");
List<Predicate> predicates = new ArrayList<>();
if (!principal.hasPermission("any_group:read")) {
Join<User, Group> userJoin = groupRoot.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(groupRoot.get("name"), likeExpr, '_'));
});
if (!predicates.isEmpty()) {
query.where(predicates.toArray(Predicate[]::new));
}
if (embedEntities.stream().anyMatch(r -> r.getName().equalsIgnoreCase("users"))) {
groupGraph.addAttributeNodes("users");
groupGraph.addSubgraph("users")
.addAttributeNodes("account");
}
return em.createQuery(query)
.setHint("javax.persistence.fetchgraph", groupGraph)
.setFirstResult(params.getOffset())
.setMaxResults(params.getLimit())
.getResultList();
}
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()))));
}
@Override
public EntityGraph<?> createEntityGraph( String string )
{
throw new UnsupportedOperationException( "Not supported yet." ); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void setPlan(EntityGraph<R> entityGraph) {
throw new UnsupportedOperationException("native SQL query cannot have a fetch plan");
}
@Override
public void setPlan(EntityGraph<R> entityGraph) {
applyGraph( (RootGraph) entityGraph, GraphSemantic.FETCH );
applyEntityGraphQueryHint( new EntityGraphQueryHint( HINT_FETCHGRAPH, (RootGraphImpl) entityGraph ) );
}
@Override
public <T> List<EntityGraph<? super T>> getEntityGraphs(final Class<T> entityClass) {
return delegate.getEntityGraphs(entityClass);
}
@Override
public <T> EntityGraph<T> getEntityGraph(Class<T> entity, String name) {
return delegate.getEntityGraph(entity, name);
}
@Override
public <T> EntityGraph<T> createEntityGraph(Class<T> entity) {
return delegate.createEntityGraph(entity);
}
@Override
public <T> EntityGraph<T> createEntityGraph(Class<T> entity, String name) {
return delegate.createEntityGraph(entity, name);
}
@Override
public <T> EntityGraph<T> getEntityGraph(Class<T> entity, String name) {
return delegate.getEntityGraph(entity, name);
}