Mapping postgres function that returns table with Hibernate












1















I have searched all over stackoverflow and other sites but i cannot figure out how to map tables that are returned from postgres functions with Hibernate in an Spring application.



I am not even sure if the return type table from postgres function can be matched with MyCustomTable somehow.



What i am trying to do is to call postgres functions (stored procedures) from spring app with hibernate.



i have this postgres function



CREATE OR REPLACE FUNCTION func99(type text,start_date TIMESTAMP, end_date TIMESTAMP) RETURNS TABLE(
some_day TIMESTAMP,
tot_requests BIGINT)
AS $$
BEGIN
RETURN QUERY
SELECT t1.first_date, COUNT(*) FROM table1 t1
WHERE t1.request_type = type and t1.first_date > start_date and t1.first_date < end_date;
END;
$$ LANGUAGE PLpgSQL;


Controller



@GetMapping("/users/{username}/func99")
public List<MyCustomTable> getResultsFromFunc99(@PathVariable(value = "username") String username,
@CurrentUser UserPrincipal currentUser,
@RequestParam(value = "service_type") String type,
@RequestParam(value = "start_date") Timestamp startDate,
@RequestParam(value = "end_date") Timestamp endDate){

return queryService.getResultsFromFunc99(username, currentUser, type, startDate, endDate);
}


Service



public List<MyCustomTable> getResultsFromFunc99(String username, UserPrincipal currentUser, String type, Timestamp startDate, Timestamp endDate) {

User user = userRepository.findByUsername(username)
.orElseThrow(() -> new ResourceNotFoundException("User", "username", username));


return return incidentRepository.func99(type, startDate, endDate);


Repository



@Procedure(procedureName = "func99")
List<MyCustomTable> func99(String type, Timestamp startDate, Timestamp endDate);


Entity



@Entity
@NamedStoredProcedureQuery(
name = "func99",
procedureName = "func99",
parameters = {
@StoredProcedureParameter(name = "type", mode = ParameterMode.IN, type = String.class),
@StoredProcedureParameter(name = "start_date", mode = ParameterMode.IN, type = Timestamp.class),
@StoredProcedureParameter(name = "end_date", mode = ParameterMode.IN, type = Timestamp.class)
}
)
@Table(name = "table1")
public class MyCustomTable {...}


When a postgres function returns an integer i can make it work. What can i do to map table returns from postgres functions and how i integrate it with Hibernate?



Any help is much appreciated!
Thanks a lot!










share|improve this question























  • The error I get is:Type cannot be null; nested exception is java.lang.IllegalArgumentException: Type cannot be null

    – paraflou
    Nov 26 '18 at 13:14
















1















I have searched all over stackoverflow and other sites but i cannot figure out how to map tables that are returned from postgres functions with Hibernate in an Spring application.



I am not even sure if the return type table from postgres function can be matched with MyCustomTable somehow.



What i am trying to do is to call postgres functions (stored procedures) from spring app with hibernate.



i have this postgres function



CREATE OR REPLACE FUNCTION func99(type text,start_date TIMESTAMP, end_date TIMESTAMP) RETURNS TABLE(
some_day TIMESTAMP,
tot_requests BIGINT)
AS $$
BEGIN
RETURN QUERY
SELECT t1.first_date, COUNT(*) FROM table1 t1
WHERE t1.request_type = type and t1.first_date > start_date and t1.first_date < end_date;
END;
$$ LANGUAGE PLpgSQL;


Controller



@GetMapping("/users/{username}/func99")
public List<MyCustomTable> getResultsFromFunc99(@PathVariable(value = "username") String username,
@CurrentUser UserPrincipal currentUser,
@RequestParam(value = "service_type") String type,
@RequestParam(value = "start_date") Timestamp startDate,
@RequestParam(value = "end_date") Timestamp endDate){

return queryService.getResultsFromFunc99(username, currentUser, type, startDate, endDate);
}


Service



public List<MyCustomTable> getResultsFromFunc99(String username, UserPrincipal currentUser, String type, Timestamp startDate, Timestamp endDate) {

User user = userRepository.findByUsername(username)
.orElseThrow(() -> new ResourceNotFoundException("User", "username", username));


return return incidentRepository.func99(type, startDate, endDate);


Repository



@Procedure(procedureName = "func99")
List<MyCustomTable> func99(String type, Timestamp startDate, Timestamp endDate);


Entity



@Entity
@NamedStoredProcedureQuery(
name = "func99",
procedureName = "func99",
parameters = {
@StoredProcedureParameter(name = "type", mode = ParameterMode.IN, type = String.class),
@StoredProcedureParameter(name = "start_date", mode = ParameterMode.IN, type = Timestamp.class),
@StoredProcedureParameter(name = "end_date", mode = ParameterMode.IN, type = Timestamp.class)
}
)
@Table(name = "table1")
public class MyCustomTable {...}


When a postgres function returns an integer i can make it work. What can i do to map table returns from postgres functions and how i integrate it with Hibernate?



Any help is much appreciated!
Thanks a lot!










share|improve this question























  • The error I get is:Type cannot be null; nested exception is java.lang.IllegalArgumentException: Type cannot be null

    – paraflou
    Nov 26 '18 at 13:14














1












1








1








I have searched all over stackoverflow and other sites but i cannot figure out how to map tables that are returned from postgres functions with Hibernate in an Spring application.



I am not even sure if the return type table from postgres function can be matched with MyCustomTable somehow.



What i am trying to do is to call postgres functions (stored procedures) from spring app with hibernate.



i have this postgres function



CREATE OR REPLACE FUNCTION func99(type text,start_date TIMESTAMP, end_date TIMESTAMP) RETURNS TABLE(
some_day TIMESTAMP,
tot_requests BIGINT)
AS $$
BEGIN
RETURN QUERY
SELECT t1.first_date, COUNT(*) FROM table1 t1
WHERE t1.request_type = type and t1.first_date > start_date and t1.first_date < end_date;
END;
$$ LANGUAGE PLpgSQL;


Controller



@GetMapping("/users/{username}/func99")
public List<MyCustomTable> getResultsFromFunc99(@PathVariable(value = "username") String username,
@CurrentUser UserPrincipal currentUser,
@RequestParam(value = "service_type") String type,
@RequestParam(value = "start_date") Timestamp startDate,
@RequestParam(value = "end_date") Timestamp endDate){

return queryService.getResultsFromFunc99(username, currentUser, type, startDate, endDate);
}


Service



public List<MyCustomTable> getResultsFromFunc99(String username, UserPrincipal currentUser, String type, Timestamp startDate, Timestamp endDate) {

User user = userRepository.findByUsername(username)
.orElseThrow(() -> new ResourceNotFoundException("User", "username", username));


return return incidentRepository.func99(type, startDate, endDate);


Repository



@Procedure(procedureName = "func99")
List<MyCustomTable> func99(String type, Timestamp startDate, Timestamp endDate);


Entity



@Entity
@NamedStoredProcedureQuery(
name = "func99",
procedureName = "func99",
parameters = {
@StoredProcedureParameter(name = "type", mode = ParameterMode.IN, type = String.class),
@StoredProcedureParameter(name = "start_date", mode = ParameterMode.IN, type = Timestamp.class),
@StoredProcedureParameter(name = "end_date", mode = ParameterMode.IN, type = Timestamp.class)
}
)
@Table(name = "table1")
public class MyCustomTable {...}


When a postgres function returns an integer i can make it work. What can i do to map table returns from postgres functions and how i integrate it with Hibernate?



Any help is much appreciated!
Thanks a lot!










share|improve this question














I have searched all over stackoverflow and other sites but i cannot figure out how to map tables that are returned from postgres functions with Hibernate in an Spring application.



I am not even sure if the return type table from postgres function can be matched with MyCustomTable somehow.



What i am trying to do is to call postgres functions (stored procedures) from spring app with hibernate.



i have this postgres function



CREATE OR REPLACE FUNCTION func99(type text,start_date TIMESTAMP, end_date TIMESTAMP) RETURNS TABLE(
some_day TIMESTAMP,
tot_requests BIGINT)
AS $$
BEGIN
RETURN QUERY
SELECT t1.first_date, COUNT(*) FROM table1 t1
WHERE t1.request_type = type and t1.first_date > start_date and t1.first_date < end_date;
END;
$$ LANGUAGE PLpgSQL;


Controller



@GetMapping("/users/{username}/func99")
public List<MyCustomTable> getResultsFromFunc99(@PathVariable(value = "username") String username,
@CurrentUser UserPrincipal currentUser,
@RequestParam(value = "service_type") String type,
@RequestParam(value = "start_date") Timestamp startDate,
@RequestParam(value = "end_date") Timestamp endDate){

return queryService.getResultsFromFunc99(username, currentUser, type, startDate, endDate);
}


Service



public List<MyCustomTable> getResultsFromFunc99(String username, UserPrincipal currentUser, String type, Timestamp startDate, Timestamp endDate) {

User user = userRepository.findByUsername(username)
.orElseThrow(() -> new ResourceNotFoundException("User", "username", username));


return return incidentRepository.func99(type, startDate, endDate);


Repository



@Procedure(procedureName = "func99")
List<MyCustomTable> func99(String type, Timestamp startDate, Timestamp endDate);


Entity



@Entity
@NamedStoredProcedureQuery(
name = "func99",
procedureName = "func99",
parameters = {
@StoredProcedureParameter(name = "type", mode = ParameterMode.IN, type = String.class),
@StoredProcedureParameter(name = "start_date", mode = ParameterMode.IN, type = Timestamp.class),
@StoredProcedureParameter(name = "end_date", mode = ParameterMode.IN, type = Timestamp.class)
}
)
@Table(name = "table1")
public class MyCustomTable {...}


When a postgres function returns an integer i can make it work. What can i do to map table returns from postgres functions and how i integrate it with Hibernate?



Any help is much appreciated!
Thanks a lot!







sql spring postgresql hibernate jpa






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 26 '18 at 13:09









paraflouparaflou

108119




108119













  • The error I get is:Type cannot be null; nested exception is java.lang.IllegalArgumentException: Type cannot be null

    – paraflou
    Nov 26 '18 at 13:14



















  • The error I get is:Type cannot be null; nested exception is java.lang.IllegalArgumentException: Type cannot be null

    – paraflou
    Nov 26 '18 at 13:14

















The error I get is:Type cannot be null; nested exception is java.lang.IllegalArgumentException: Type cannot be null

– paraflou
Nov 26 '18 at 13:14





The error I get is:Type cannot be null; nested exception is java.lang.IllegalArgumentException: Type cannot be null

– paraflou
Nov 26 '18 at 13:14












2 Answers
2






active

oldest

votes


















0














This is a workaround I use for a similar problem, but it might work.



Define a SqlResultSetMapping like this:



@SqlResultSetMapping(
name = "MyCustomTableMapping",
entities = @EntityResult(entityClass = MyCustomTable.class)
)


Then change this parameter to your NamedStoredProcedureQuery annotation:



resultSetMappings = "MyCustomTableMapping"


I use this technique with NamedNativeQueries to make sure Hibernate doesn't track them for changes like actual entities. Saves me and my colleagues from having to remember to detach lots of entities. Just about every tutorial on how to use search results that don't correspond to a table will leave you with that problem and treat it as okay.






share|improve this answer































    0














    I found a working solution.



    I don't use the method from repository.
    Instead of the aforementioned repository:



    *@Procedure(procedureName = "func99")
    List<MyCustomTable> func99(String type, Timestamp startDate, Timestamp endDate);*


    I know do this inside service without using the repository:



    @PersistenceContext
    EntityManager em;


    .



    public List<MyCustomTable> getResultsFromFunc99(String username, UserPrincipal currentUser, String type, Timestamp startDate, Timestamp endDate) {
    User user = userRepository.findByUsername(username)
    .orElseThrow(() -> new ResourceNotFoundException("User", "username", username));

    Query query = em.createNamedStoredProcedureQuery("func99");
    query.setParameter("some_day", someDay);
    ((StoredProcedureQuery) query).execute();

    return query.getResultList()


    Entity class remains the same where i declare



    @Entity
    @NamedStoredProcedureQuery(
    name = "func99",
    procedureName = "func99",
    parameters = {
    @StoredProcedureParameter(name = "type", mode = ParameterMode.IN, type = String.class),
    @StoredProcedureParameter(name = "start_date", mode = ParameterMode.IN, type = Timestamp.class),
    @StoredProcedureParameter(name = "end_date", mode = ParameterMode.IN, type = Timestamp.class)
    }
    )
    @Table(name = "table1")
    public class MyCustomTable {...}





    share|improve this answer
























      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%2f53481836%2fmapping-postgres-function-that-returns-table-with-hibernate%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









      0














      This is a workaround I use for a similar problem, but it might work.



      Define a SqlResultSetMapping like this:



      @SqlResultSetMapping(
      name = "MyCustomTableMapping",
      entities = @EntityResult(entityClass = MyCustomTable.class)
      )


      Then change this parameter to your NamedStoredProcedureQuery annotation:



      resultSetMappings = "MyCustomTableMapping"


      I use this technique with NamedNativeQueries to make sure Hibernate doesn't track them for changes like actual entities. Saves me and my colleagues from having to remember to detach lots of entities. Just about every tutorial on how to use search results that don't correspond to a table will leave you with that problem and treat it as okay.






      share|improve this answer




























        0














        This is a workaround I use for a similar problem, but it might work.



        Define a SqlResultSetMapping like this:



        @SqlResultSetMapping(
        name = "MyCustomTableMapping",
        entities = @EntityResult(entityClass = MyCustomTable.class)
        )


        Then change this parameter to your NamedStoredProcedureQuery annotation:



        resultSetMappings = "MyCustomTableMapping"


        I use this technique with NamedNativeQueries to make sure Hibernate doesn't track them for changes like actual entities. Saves me and my colleagues from having to remember to detach lots of entities. Just about every tutorial on how to use search results that don't correspond to a table will leave you with that problem and treat it as okay.






        share|improve this answer


























          0












          0








          0







          This is a workaround I use for a similar problem, but it might work.



          Define a SqlResultSetMapping like this:



          @SqlResultSetMapping(
          name = "MyCustomTableMapping",
          entities = @EntityResult(entityClass = MyCustomTable.class)
          )


          Then change this parameter to your NamedStoredProcedureQuery annotation:



          resultSetMappings = "MyCustomTableMapping"


          I use this technique with NamedNativeQueries to make sure Hibernate doesn't track them for changes like actual entities. Saves me and my colleagues from having to remember to detach lots of entities. Just about every tutorial on how to use search results that don't correspond to a table will leave you with that problem and treat it as okay.






          share|improve this answer













          This is a workaround I use for a similar problem, but it might work.



          Define a SqlResultSetMapping like this:



          @SqlResultSetMapping(
          name = "MyCustomTableMapping",
          entities = @EntityResult(entityClass = MyCustomTable.class)
          )


          Then change this parameter to your NamedStoredProcedureQuery annotation:



          resultSetMappings = "MyCustomTableMapping"


          I use this technique with NamedNativeQueries to make sure Hibernate doesn't track them for changes like actual entities. Saves me and my colleagues from having to remember to detach lots of entities. Just about every tutorial on how to use search results that don't correspond to a table will leave you with that problem and treat it as okay.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 26 '18 at 18:58









          coladictcoladict

          1,954517




          1,954517

























              0














              I found a working solution.



              I don't use the method from repository.
              Instead of the aforementioned repository:



              *@Procedure(procedureName = "func99")
              List<MyCustomTable> func99(String type, Timestamp startDate, Timestamp endDate);*


              I know do this inside service without using the repository:



              @PersistenceContext
              EntityManager em;


              .



              public List<MyCustomTable> getResultsFromFunc99(String username, UserPrincipal currentUser, String type, Timestamp startDate, Timestamp endDate) {
              User user = userRepository.findByUsername(username)
              .orElseThrow(() -> new ResourceNotFoundException("User", "username", username));

              Query query = em.createNamedStoredProcedureQuery("func99");
              query.setParameter("some_day", someDay);
              ((StoredProcedureQuery) query).execute();

              return query.getResultList()


              Entity class remains the same where i declare



              @Entity
              @NamedStoredProcedureQuery(
              name = "func99",
              procedureName = "func99",
              parameters = {
              @StoredProcedureParameter(name = "type", mode = ParameterMode.IN, type = String.class),
              @StoredProcedureParameter(name = "start_date", mode = ParameterMode.IN, type = Timestamp.class),
              @StoredProcedureParameter(name = "end_date", mode = ParameterMode.IN, type = Timestamp.class)
              }
              )
              @Table(name = "table1")
              public class MyCustomTable {...}





              share|improve this answer




























                0














                I found a working solution.



                I don't use the method from repository.
                Instead of the aforementioned repository:



                *@Procedure(procedureName = "func99")
                List<MyCustomTable> func99(String type, Timestamp startDate, Timestamp endDate);*


                I know do this inside service without using the repository:



                @PersistenceContext
                EntityManager em;


                .



                public List<MyCustomTable> getResultsFromFunc99(String username, UserPrincipal currentUser, String type, Timestamp startDate, Timestamp endDate) {
                User user = userRepository.findByUsername(username)
                .orElseThrow(() -> new ResourceNotFoundException("User", "username", username));

                Query query = em.createNamedStoredProcedureQuery("func99");
                query.setParameter("some_day", someDay);
                ((StoredProcedureQuery) query).execute();

                return query.getResultList()


                Entity class remains the same where i declare



                @Entity
                @NamedStoredProcedureQuery(
                name = "func99",
                procedureName = "func99",
                parameters = {
                @StoredProcedureParameter(name = "type", mode = ParameterMode.IN, type = String.class),
                @StoredProcedureParameter(name = "start_date", mode = ParameterMode.IN, type = Timestamp.class),
                @StoredProcedureParameter(name = "end_date", mode = ParameterMode.IN, type = Timestamp.class)
                }
                )
                @Table(name = "table1")
                public class MyCustomTable {...}





                share|improve this answer


























                  0












                  0








                  0







                  I found a working solution.



                  I don't use the method from repository.
                  Instead of the aforementioned repository:



                  *@Procedure(procedureName = "func99")
                  List<MyCustomTable> func99(String type, Timestamp startDate, Timestamp endDate);*


                  I know do this inside service without using the repository:



                  @PersistenceContext
                  EntityManager em;


                  .



                  public List<MyCustomTable> getResultsFromFunc99(String username, UserPrincipal currentUser, String type, Timestamp startDate, Timestamp endDate) {
                  User user = userRepository.findByUsername(username)
                  .orElseThrow(() -> new ResourceNotFoundException("User", "username", username));

                  Query query = em.createNamedStoredProcedureQuery("func99");
                  query.setParameter("some_day", someDay);
                  ((StoredProcedureQuery) query).execute();

                  return query.getResultList()


                  Entity class remains the same where i declare



                  @Entity
                  @NamedStoredProcedureQuery(
                  name = "func99",
                  procedureName = "func99",
                  parameters = {
                  @StoredProcedureParameter(name = "type", mode = ParameterMode.IN, type = String.class),
                  @StoredProcedureParameter(name = "start_date", mode = ParameterMode.IN, type = Timestamp.class),
                  @StoredProcedureParameter(name = "end_date", mode = ParameterMode.IN, type = Timestamp.class)
                  }
                  )
                  @Table(name = "table1")
                  public class MyCustomTable {...}





                  share|improve this answer













                  I found a working solution.



                  I don't use the method from repository.
                  Instead of the aforementioned repository:



                  *@Procedure(procedureName = "func99")
                  List<MyCustomTable> func99(String type, Timestamp startDate, Timestamp endDate);*


                  I know do this inside service without using the repository:



                  @PersistenceContext
                  EntityManager em;


                  .



                  public List<MyCustomTable> getResultsFromFunc99(String username, UserPrincipal currentUser, String type, Timestamp startDate, Timestamp endDate) {
                  User user = userRepository.findByUsername(username)
                  .orElseThrow(() -> new ResourceNotFoundException("User", "username", username));

                  Query query = em.createNamedStoredProcedureQuery("func99");
                  query.setParameter("some_day", someDay);
                  ((StoredProcedureQuery) query).execute();

                  return query.getResultList()


                  Entity class remains the same where i declare



                  @Entity
                  @NamedStoredProcedureQuery(
                  name = "func99",
                  procedureName = "func99",
                  parameters = {
                  @StoredProcedureParameter(name = "type", mode = ParameterMode.IN, type = String.class),
                  @StoredProcedureParameter(name = "start_date", mode = ParameterMode.IN, type = Timestamp.class),
                  @StoredProcedureParameter(name = "end_date", mode = ParameterMode.IN, type = Timestamp.class)
                  }
                  )
                  @Table(name = "table1")
                  public class MyCustomTable {...}






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 26 '18 at 20:40









                  paraflouparaflou

                  108119




                  108119






























                      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%2f53481836%2fmapping-postgres-function-that-returns-table-with-hibernate%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

                      Costa Masnaga

                      Fotorealismo

                      Sidney Franklin