3

How can the proper Solution (answered Jun 27, 2018 at 6:01 from user Vlad Mihalcea) https://stackoverflow.com/a/51055523/19408825 be transfered in Hibernate commands instead of query Strings? The proper sample solution:

    List<Post> posts = entityManager
    .createQuery(
        "select distinct p " +
        "from Post p " +
        "left join fetch p.comments " +
        "where p.id between :minId and :maxId ", Post.class)
    .setParameter("minId", 1L)
    .setParameter("maxId", 50L)
    .setHint(QueryHints.PASS_DISTINCT_THROUGH, false)
    .getResultList();
    
    posts = entityManager
    .createQuery(
        "select distinct p " +
        "from Post p " +
        "left join fetch p.tags t " +
        "where p in :posts ", Post.class)
    .setParameter("posts", posts)
    .setHint(QueryHints.PASS_DISTINCT_THROUGH, false)
    .getResultList();

According to coding guidlines we must use Hibernate commands instead of the Strings. I already put weeks of work into it and one of my 50 different trials (which are not working) look something like the following.

Class Post:

    // Post Class with two lists that are needed in the same time
    public class Post {
        
        ...
    
        @OneToMany(mappedBy = "post", fetch = FetchType.LAZY)
        private List<Comment> comments;
    
        @OneToMany(mappedBy = "post", fetch = FetchType.LAZY)
        private List<Tag> tags;
        
        ...
    }

Class PostService:

    public class PostService {
        ...
        
        public List<Post> findingAllPosts() {
            CriteriaBuilder builder = entityManager.getCriteriaBuilder();
            
            CriteriaQuery<Post> criteria = builder.createQuery(Post.class);
            Root<Post> root = criteria.from(Post.class);
            
            root.fetch(Post_.comments, JoinType.LEFT);
            criteria.select(root);
            criteria.distinct(true);
            
            List<Post> posts = entityManager
                    .createQuery(criteria)
                    .setHint(QueryHints.HINT_PASS_DISTINCT_THROUGH, false)
                    .getResultList();
            
            root.fetch(Post_.tags, JoinType.LEFT);
            // different approaches ... one is:
            criteria.select(root)
                .where(root
                    .in(":posts")
                );
            
            posts = entityManager
                .createQuery(criteria)
                .setParameter("posts", posts)
                .setHint(QueryHints.HINT_PASS_DISTINCT_THROUGH, false)
                .getResultList();
                
            return posts;
        }
    }

This and similar other Trials throw the Exception:

    org.hibernate.QueryException:
    query specified join fetching, but the owner of the
    fetched association was not present in the select list
    [FromElement{explicit,not a collection join,fetch join,
    fetch non-lazy properties,
    classAlias=generatedAlias1,
    role=at.test.Post.comments,
    tableName=TEST.COMMENT,
    tableAlias=comment1_,
    origin=TEST.POST post0_,columns={post0_.ID ,className=at.test.Comment}}]
    [
    select distinct generatedAlias0
    from at.test.Post as generatedAlias0
    left join fetch generatedAlias0.comments as generatedAlias1
    left join fetch generatedAlias0.tags as generatedAlias0
    where generatedAlias0 in (:param0)
    ]:
    javax.ejb.EJBTransactionRolledbackException:
    org.hibernate.QueryException:
    query specified join fetching, but the owner of the
    fetched association was not present in the select list
    [FromElement{explicit,not a collection join,fetch join,
    fetch non-lazy properties,
    classAlias=generatedAlias1,
    role=at.test.Post.comments,
    tableName=TEST.COMMENT,
    tableAlias=comment1_,
    origin=TEST.POST post0_,
    columns={post0_.ID ,className=at.test.Comment}}]
    [
    select distinct generatedAlias0
    from at.test.Post as generatedAlias0
    left join fetch generatedAlias0.comments as generatedAlias1
    left join fetch generatedAlias0.tags as generatedAlias0
    where generatedAlias0 in (:param0)]
    

Where I am unsure is, how I use the "in" clause in Hibernate. Maybe there is an Problem in the line

    ... "where p in :posts ", Post.class)

which I translated to

    ... .where(root.in(":posts"));

Does anybody know how to use the "in"-Clause in the right way? Or how can this Query Strings can be translated to Hibernate commands like I tried?

Thanks a lot in advance! Would be very important.

HyperFreak
  • 31
  • 3

0 Answers0