JPA Criteria query for a nested set












0















I have a Person entity within that entity I have a nested Set of entities for PersonNames. There is a OneToMany relationship between Person and PersonNames in that a person can have a multiple names.



    @XmlElementWrapper(name = "names")
@XmlElement(name = "name")
@OneToMany(mappedBy = "person", orphanRemoval = false, fetch = FetchType.EAGER)
private Set<PersonNames> name;


You can see how the PersonNames set is defined above.



I need to create a JPA Criteria query for finding all Person entities that have a PersonNames object matching on firstName, middleName, or lastName.



public List<Person> getPerson(String lastName, String middleName, String firstName) {
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<Person> criteria = builder.createQuery(Person.class);

Root<Person> root = criteria.from(Person.class);
criteria.select(root);

if(!lastName.isEmpty() && lastName != null) {
Predicate lastNameCondition = builder.equal( root.get(Person_.personId).get(PersonNames_.lastName), lastName);
criteria.where(lastNameCondition);
}

TypedQuery<Person> query = em.createQuery(criteria);
return query.getResultList();
}


Above is my attempt to accomplish said query, however I get the following error on the ".get(Person_.personId)" part of the Predicate line:



The method get(SingularAttribute) in the type Path is not applicable for the arguments (SingularAttribute)



The predicate line might be completely wrong, but I can't wrap my head on how to accomplish this, and nothing I google seems to turn up any results. Do I need to do an explicit join for this?



Edit: Removed Hibernate tag as I realized it's what our Wildfly server wants to use, but we are not using Hibernate in our code.










share|improve this question





























    0















    I have a Person entity within that entity I have a nested Set of entities for PersonNames. There is a OneToMany relationship between Person and PersonNames in that a person can have a multiple names.



        @XmlElementWrapper(name = "names")
    @XmlElement(name = "name")
    @OneToMany(mappedBy = "person", orphanRemoval = false, fetch = FetchType.EAGER)
    private Set<PersonNames> name;


    You can see how the PersonNames set is defined above.



    I need to create a JPA Criteria query for finding all Person entities that have a PersonNames object matching on firstName, middleName, or lastName.



    public List<Person> getPerson(String lastName, String middleName, String firstName) {
    CriteriaBuilder builder = em.getCriteriaBuilder();
    CriteriaQuery<Person> criteria = builder.createQuery(Person.class);

    Root<Person> root = criteria.from(Person.class);
    criteria.select(root);

    if(!lastName.isEmpty() && lastName != null) {
    Predicate lastNameCondition = builder.equal( root.get(Person_.personId).get(PersonNames_.lastName), lastName);
    criteria.where(lastNameCondition);
    }

    TypedQuery<Person> query = em.createQuery(criteria);
    return query.getResultList();
    }


    Above is my attempt to accomplish said query, however I get the following error on the ".get(Person_.personId)" part of the Predicate line:



    The method get(SingularAttribute) in the type Path is not applicable for the arguments (SingularAttribute)



    The predicate line might be completely wrong, but I can't wrap my head on how to accomplish this, and nothing I google seems to turn up any results. Do I need to do an explicit join for this?



    Edit: Removed Hibernate tag as I realized it's what our Wildfly server wants to use, but we are not using Hibernate in our code.










    share|improve this question



























      0












      0








      0








      I have a Person entity within that entity I have a nested Set of entities for PersonNames. There is a OneToMany relationship between Person and PersonNames in that a person can have a multiple names.



          @XmlElementWrapper(name = "names")
      @XmlElement(name = "name")
      @OneToMany(mappedBy = "person", orphanRemoval = false, fetch = FetchType.EAGER)
      private Set<PersonNames> name;


      You can see how the PersonNames set is defined above.



      I need to create a JPA Criteria query for finding all Person entities that have a PersonNames object matching on firstName, middleName, or lastName.



      public List<Person> getPerson(String lastName, String middleName, String firstName) {
      CriteriaBuilder builder = em.getCriteriaBuilder();
      CriteriaQuery<Person> criteria = builder.createQuery(Person.class);

      Root<Person> root = criteria.from(Person.class);
      criteria.select(root);

      if(!lastName.isEmpty() && lastName != null) {
      Predicate lastNameCondition = builder.equal( root.get(Person_.personId).get(PersonNames_.lastName), lastName);
      criteria.where(lastNameCondition);
      }

      TypedQuery<Person> query = em.createQuery(criteria);
      return query.getResultList();
      }


      Above is my attempt to accomplish said query, however I get the following error on the ".get(Person_.personId)" part of the Predicate line:



      The method get(SingularAttribute) in the type Path is not applicable for the arguments (SingularAttribute)



      The predicate line might be completely wrong, but I can't wrap my head on how to accomplish this, and nothing I google seems to turn up any results. Do I need to do an explicit join for this?



      Edit: Removed Hibernate tag as I realized it's what our Wildfly server wants to use, but we are not using Hibernate in our code.










      share|improve this question
















      I have a Person entity within that entity I have a nested Set of entities for PersonNames. There is a OneToMany relationship between Person and PersonNames in that a person can have a multiple names.



          @XmlElementWrapper(name = "names")
      @XmlElement(name = "name")
      @OneToMany(mappedBy = "person", orphanRemoval = false, fetch = FetchType.EAGER)
      private Set<PersonNames> name;


      You can see how the PersonNames set is defined above.



      I need to create a JPA Criteria query for finding all Person entities that have a PersonNames object matching on firstName, middleName, or lastName.



      public List<Person> getPerson(String lastName, String middleName, String firstName) {
      CriteriaBuilder builder = em.getCriteriaBuilder();
      CriteriaQuery<Person> criteria = builder.createQuery(Person.class);

      Root<Person> root = criteria.from(Person.class);
      criteria.select(root);

      if(!lastName.isEmpty() && lastName != null) {
      Predicate lastNameCondition = builder.equal( root.get(Person_.personId).get(PersonNames_.lastName), lastName);
      criteria.where(lastNameCondition);
      }

      TypedQuery<Person> query = em.createQuery(criteria);
      return query.getResultList();
      }


      Above is my attempt to accomplish said query, however I get the following error on the ".get(Person_.personId)" part of the Predicate line:



      The method get(SingularAttribute) in the type Path is not applicable for the arguments (SingularAttribute)



      The predicate line might be completely wrong, but I can't wrap my head on how to accomplish this, and nothing I google seems to turn up any results. Do I need to do an explicit join for this?



      Edit: Removed Hibernate tag as I realized it's what our Wildfly server wants to use, but we are not using Hibernate in our code.







      java jpa jaxb criteria-api






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 15 '18 at 0:31







      Eric

















      asked Nov 14 '18 at 23:35









      EricEric

      326521




      326521
























          2 Answers
          2






          active

          oldest

          votes


















          1














          Re: "not using Hibernate API in our code" -- it is being deprecated.



          CriteriaApi has a few detractors, but regardless, once you get the hang of things it can be approached pretty easily.



          @Entity
          public class Person {
          @Id @GeneratedValue(strategy=GenerationType.IDENTITY)
          private Long id;

          @OneToMany(mappedBy="person")
          private Set<PersonName> names;


          and to populate it:



          tx.begin();
          Person p = new Person();
          PersonName c1 = new PersonName(p, "F1", "M1", "L1");
          PersonName c2 = new PersonName(p, "F2", "M2", "L2");
          em.persist(p);
          em.persist(c1);
          em.persist(c2);
          tx.commit();


          and to query it



          em.clear();
          CriteriaBuilder cb = em.getCriteriaBuilder();
          CriteriaQuery<Person> query = cb.createQuery(Person.class);
          Root<Person> person = query.from(Person.class);
          Join<Person, PersonName> names = person.join("names");
          Predicate findNames = new Predicate[3];
          findNames[0] = cb.equal(names.get("firstName"), "F1");
          findNames[1] = cb.equal(names.get("middleName"), "M1");
          findNames[2] = cb.equal(names.get("lastName"), "L1");
          query.where(findNames);
          List<Person> persons = em.createQuery(query).getResultList();
          System.out.println(persons);





          share|improve this answer





















          • 1





            Brilliant! Worked perfectly! Thank you so much, and you say that Hibernate is being deprecated?

            – Eric
            Nov 15 '18 at 2:39











          • I just mean the API is deprecated. Hibernate is still a provider for JPA. stackoverflow.com/questions/50073875/…

            – K.Nicholas
            Nov 15 '18 at 2:42





















          0














          Will this work?



          Criteria c = s.createCriteria(Person.class);
          c.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
          c.createAlias("name", "name");
          c.add(Restrictions.eq("name.lastName", lastName));
          return c.list();





          share|improve this answer
























          • Potentially, but I'm an idiot and realized that our Wildfly server wants to use Hibernate, hence why it was on my mind, but we are not using Hibernate API in our code(We can if we can't find a barebones JPA Criteria way to do it).

            – Eric
            Nov 15 '18 at 0:32











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53310358%2fjpa-criteria-query-for-a-nested-set%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          2 Answers
          2






          active

          oldest

          votes








          2 Answers
          2






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          1














          Re: "not using Hibernate API in our code" -- it is being deprecated.



          CriteriaApi has a few detractors, but regardless, once you get the hang of things it can be approached pretty easily.



          @Entity
          public class Person {
          @Id @GeneratedValue(strategy=GenerationType.IDENTITY)
          private Long id;

          @OneToMany(mappedBy="person")
          private Set<PersonName> names;


          and to populate it:



          tx.begin();
          Person p = new Person();
          PersonName c1 = new PersonName(p, "F1", "M1", "L1");
          PersonName c2 = new PersonName(p, "F2", "M2", "L2");
          em.persist(p);
          em.persist(c1);
          em.persist(c2);
          tx.commit();


          and to query it



          em.clear();
          CriteriaBuilder cb = em.getCriteriaBuilder();
          CriteriaQuery<Person> query = cb.createQuery(Person.class);
          Root<Person> person = query.from(Person.class);
          Join<Person, PersonName> names = person.join("names");
          Predicate findNames = new Predicate[3];
          findNames[0] = cb.equal(names.get("firstName"), "F1");
          findNames[1] = cb.equal(names.get("middleName"), "M1");
          findNames[2] = cb.equal(names.get("lastName"), "L1");
          query.where(findNames);
          List<Person> persons = em.createQuery(query).getResultList();
          System.out.println(persons);





          share|improve this answer





















          • 1





            Brilliant! Worked perfectly! Thank you so much, and you say that Hibernate is being deprecated?

            – Eric
            Nov 15 '18 at 2:39











          • I just mean the API is deprecated. Hibernate is still a provider for JPA. stackoverflow.com/questions/50073875/…

            – K.Nicholas
            Nov 15 '18 at 2:42


















          1














          Re: "not using Hibernate API in our code" -- it is being deprecated.



          CriteriaApi has a few detractors, but regardless, once you get the hang of things it can be approached pretty easily.



          @Entity
          public class Person {
          @Id @GeneratedValue(strategy=GenerationType.IDENTITY)
          private Long id;

          @OneToMany(mappedBy="person")
          private Set<PersonName> names;


          and to populate it:



          tx.begin();
          Person p = new Person();
          PersonName c1 = new PersonName(p, "F1", "M1", "L1");
          PersonName c2 = new PersonName(p, "F2", "M2", "L2");
          em.persist(p);
          em.persist(c1);
          em.persist(c2);
          tx.commit();


          and to query it



          em.clear();
          CriteriaBuilder cb = em.getCriteriaBuilder();
          CriteriaQuery<Person> query = cb.createQuery(Person.class);
          Root<Person> person = query.from(Person.class);
          Join<Person, PersonName> names = person.join("names");
          Predicate findNames = new Predicate[3];
          findNames[0] = cb.equal(names.get("firstName"), "F1");
          findNames[1] = cb.equal(names.get("middleName"), "M1");
          findNames[2] = cb.equal(names.get("lastName"), "L1");
          query.where(findNames);
          List<Person> persons = em.createQuery(query).getResultList();
          System.out.println(persons);





          share|improve this answer





















          • 1





            Brilliant! Worked perfectly! Thank you so much, and you say that Hibernate is being deprecated?

            – Eric
            Nov 15 '18 at 2:39











          • I just mean the API is deprecated. Hibernate is still a provider for JPA. stackoverflow.com/questions/50073875/…

            – K.Nicholas
            Nov 15 '18 at 2:42
















          1












          1








          1







          Re: "not using Hibernate API in our code" -- it is being deprecated.



          CriteriaApi has a few detractors, but regardless, once you get the hang of things it can be approached pretty easily.



          @Entity
          public class Person {
          @Id @GeneratedValue(strategy=GenerationType.IDENTITY)
          private Long id;

          @OneToMany(mappedBy="person")
          private Set<PersonName> names;


          and to populate it:



          tx.begin();
          Person p = new Person();
          PersonName c1 = new PersonName(p, "F1", "M1", "L1");
          PersonName c2 = new PersonName(p, "F2", "M2", "L2");
          em.persist(p);
          em.persist(c1);
          em.persist(c2);
          tx.commit();


          and to query it



          em.clear();
          CriteriaBuilder cb = em.getCriteriaBuilder();
          CriteriaQuery<Person> query = cb.createQuery(Person.class);
          Root<Person> person = query.from(Person.class);
          Join<Person, PersonName> names = person.join("names");
          Predicate findNames = new Predicate[3];
          findNames[0] = cb.equal(names.get("firstName"), "F1");
          findNames[1] = cb.equal(names.get("middleName"), "M1");
          findNames[2] = cb.equal(names.get("lastName"), "L1");
          query.where(findNames);
          List<Person> persons = em.createQuery(query).getResultList();
          System.out.println(persons);





          share|improve this answer















          Re: "not using Hibernate API in our code" -- it is being deprecated.



          CriteriaApi has a few detractors, but regardless, once you get the hang of things it can be approached pretty easily.



          @Entity
          public class Person {
          @Id @GeneratedValue(strategy=GenerationType.IDENTITY)
          private Long id;

          @OneToMany(mappedBy="person")
          private Set<PersonName> names;


          and to populate it:



          tx.begin();
          Person p = new Person();
          PersonName c1 = new PersonName(p, "F1", "M1", "L1");
          PersonName c2 = new PersonName(p, "F2", "M2", "L2");
          em.persist(p);
          em.persist(c1);
          em.persist(c2);
          tx.commit();


          and to query it



          em.clear();
          CriteriaBuilder cb = em.getCriteriaBuilder();
          CriteriaQuery<Person> query = cb.createQuery(Person.class);
          Root<Person> person = query.from(Person.class);
          Join<Person, PersonName> names = person.join("names");
          Predicate findNames = new Predicate[3];
          findNames[0] = cb.equal(names.get("firstName"), "F1");
          findNames[1] = cb.equal(names.get("middleName"), "M1");
          findNames[2] = cb.equal(names.get("lastName"), "L1");
          query.where(findNames);
          List<Person> persons = em.createQuery(query).getResultList();
          System.out.println(persons);






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 15 '18 at 2:27

























          answered Nov 15 '18 at 2:09









          K.NicholasK.Nicholas

          5,31932440




          5,31932440








          • 1





            Brilliant! Worked perfectly! Thank you so much, and you say that Hibernate is being deprecated?

            – Eric
            Nov 15 '18 at 2:39











          • I just mean the API is deprecated. Hibernate is still a provider for JPA. stackoverflow.com/questions/50073875/…

            – K.Nicholas
            Nov 15 '18 at 2:42
















          • 1





            Brilliant! Worked perfectly! Thank you so much, and you say that Hibernate is being deprecated?

            – Eric
            Nov 15 '18 at 2:39











          • I just mean the API is deprecated. Hibernate is still a provider for JPA. stackoverflow.com/questions/50073875/…

            – K.Nicholas
            Nov 15 '18 at 2:42










          1




          1





          Brilliant! Worked perfectly! Thank you so much, and you say that Hibernate is being deprecated?

          – Eric
          Nov 15 '18 at 2:39





          Brilliant! Worked perfectly! Thank you so much, and you say that Hibernate is being deprecated?

          – Eric
          Nov 15 '18 at 2:39













          I just mean the API is deprecated. Hibernate is still a provider for JPA. stackoverflow.com/questions/50073875/…

          – K.Nicholas
          Nov 15 '18 at 2:42







          I just mean the API is deprecated. Hibernate is still a provider for JPA. stackoverflow.com/questions/50073875/…

          – K.Nicholas
          Nov 15 '18 at 2:42















          0














          Will this work?



          Criteria c = s.createCriteria(Person.class);
          c.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
          c.createAlias("name", "name");
          c.add(Restrictions.eq("name.lastName", lastName));
          return c.list();





          share|improve this answer
























          • Potentially, but I'm an idiot and realized that our Wildfly server wants to use Hibernate, hence why it was on my mind, but we are not using Hibernate API in our code(We can if we can't find a barebones JPA Criteria way to do it).

            – Eric
            Nov 15 '18 at 0:32
















          0














          Will this work?



          Criteria c = s.createCriteria(Person.class);
          c.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
          c.createAlias("name", "name");
          c.add(Restrictions.eq("name.lastName", lastName));
          return c.list();





          share|improve this answer
























          • Potentially, but I'm an idiot and realized that our Wildfly server wants to use Hibernate, hence why it was on my mind, but we are not using Hibernate API in our code(We can if we can't find a barebones JPA Criteria way to do it).

            – Eric
            Nov 15 '18 at 0:32














          0












          0








          0







          Will this work?



          Criteria c = s.createCriteria(Person.class);
          c.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
          c.createAlias("name", "name");
          c.add(Restrictions.eq("name.lastName", lastName));
          return c.list();





          share|improve this answer













          Will this work?



          Criteria c = s.createCriteria(Person.class);
          c.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
          c.createAlias("name", "name");
          c.add(Restrictions.eq("name.lastName", lastName));
          return c.list();






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 15 '18 at 0:14









          JustinJustin

          1,0131511




          1,0131511













          • Potentially, but I'm an idiot and realized that our Wildfly server wants to use Hibernate, hence why it was on my mind, but we are not using Hibernate API in our code(We can if we can't find a barebones JPA Criteria way to do it).

            – Eric
            Nov 15 '18 at 0:32



















          • Potentially, but I'm an idiot and realized that our Wildfly server wants to use Hibernate, hence why it was on my mind, but we are not using Hibernate API in our code(We can if we can't find a barebones JPA Criteria way to do it).

            – Eric
            Nov 15 '18 at 0:32

















          Potentially, but I'm an idiot and realized that our Wildfly server wants to use Hibernate, hence why it was on my mind, but we are not using Hibernate API in our code(We can if we can't find a barebones JPA Criteria way to do it).

          – Eric
          Nov 15 '18 at 0:32





          Potentially, but I'm an idiot and realized that our Wildfly server wants to use Hibernate, hence why it was on my mind, but we are not using Hibernate API in our code(We can if we can't find a barebones JPA Criteria way to do it).

          – Eric
          Nov 15 '18 at 0:32


















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53310358%2fjpa-criteria-query-for-a-nested-set%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Florida Star v. B. J. F.

          Danny Elfman

          Lugert, Oklahoma