JPA/Hibernate5 get sequence nextval by sequence name











up vote
3
down vote

favorite












How can I get sequence nextval in JPA or Hibernate 5 by sequence name?



I have sequence the following TEST_SEQ in Oracle DB and ANOTHER_NAME_SEQ in Postgresql DB.



I need a method with following signature



public Long getSequenceByName(String sequenceName){}


And when I call this method it must return nextval from DB which is now used.



I have a couple of ideas, but they are not suitable.



1) Store native query for each DB in properties and write method like this:



@Value("${query}")//"SELECT {name}.NEXTVAL FROM DUAL"
private StringQuery;

public Long getSequenceByName(String sequenceName){
uery q = em.createNativeQuery(StringQuery.replace("{name}", sequenceName));
return (java.math.BigDecimal) q.getSingleResult();
}


But I need to store the query string with placeholders and replace placeholder to sequence name, store query for each DB.



2) Create entity with only one field @Id. Insert entity and getId(sequence value).



But if in different DB is different sequence names - ???



3) Use this. But It for hibernate 3 and I don't know if this is a good approach.



EDIT:



I try this solution:



@Component
public class SequenseRepository {

@PersistenceContext
private EntityManager em;

@Transactional
public Long getID(final String sequenceName) {
final List<Long> ids = new ArrayList<>(1);

Session session = em.unwrap(Session.class);
session.doWork(connection -> {
DialectResolver dialectResolver = new StandardDialectResolver();
Dialect dialect = dialectResolver.resolveDialect((DialectResolutionInfo) connection.getMetaData());
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
preparedStatement = connection.prepareStatement( dialect.getSequenceNextValString(sequenceName));
resultSet = preparedStatement.executeQuery();
resultSet.next();
ids.add(resultSet.getLong(1));
}catch (SQLException e) {
throw e;
} finally {
if(preparedStatement != null) {
preparedStatement.close();
}
if(resultSet != null) {
resultSet.close();
}
}
});

return ids.get(0);
}
}


And I get exeption:



java.lang.ClassCastException: oracle.jdbc.driver.OracleDatabaseMetaData cannot be cast to org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo









share|improve this question
























  • Possible duplicate of get next sequence value from database using hibernate
    – aurelius
    Nov 9 at 8:19










  • @aurelius can you read my question more carefully? Specifically, point 3 and see the link that I gave
    – ip696
    Nov 9 at 8:21










  • Point 3 also shows a method for hibernate 4. And using the dialect IS a good approach. (at least this is how we do and this works fine).
    – StephaneM
    Nov 9 at 8:41










  • But I use hibernate5. Thank you for sharing your information about using this approach. I also wanted to learn other approaches.
    – ip696
    Nov 9 at 8:45















up vote
3
down vote

favorite












How can I get sequence nextval in JPA or Hibernate 5 by sequence name?



I have sequence the following TEST_SEQ in Oracle DB and ANOTHER_NAME_SEQ in Postgresql DB.



I need a method with following signature



public Long getSequenceByName(String sequenceName){}


And when I call this method it must return nextval from DB which is now used.



I have a couple of ideas, but they are not suitable.



1) Store native query for each DB in properties and write method like this:



@Value("${query}")//"SELECT {name}.NEXTVAL FROM DUAL"
private StringQuery;

public Long getSequenceByName(String sequenceName){
uery q = em.createNativeQuery(StringQuery.replace("{name}", sequenceName));
return (java.math.BigDecimal) q.getSingleResult();
}


But I need to store the query string with placeholders and replace placeholder to sequence name, store query for each DB.



2) Create entity with only one field @Id. Insert entity and getId(sequence value).



But if in different DB is different sequence names - ???



3) Use this. But It for hibernate 3 and I don't know if this is a good approach.



EDIT:



I try this solution:



@Component
public class SequenseRepository {

@PersistenceContext
private EntityManager em;

@Transactional
public Long getID(final String sequenceName) {
final List<Long> ids = new ArrayList<>(1);

Session session = em.unwrap(Session.class);
session.doWork(connection -> {
DialectResolver dialectResolver = new StandardDialectResolver();
Dialect dialect = dialectResolver.resolveDialect((DialectResolutionInfo) connection.getMetaData());
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
preparedStatement = connection.prepareStatement( dialect.getSequenceNextValString(sequenceName));
resultSet = preparedStatement.executeQuery();
resultSet.next();
ids.add(resultSet.getLong(1));
}catch (SQLException e) {
throw e;
} finally {
if(preparedStatement != null) {
preparedStatement.close();
}
if(resultSet != null) {
resultSet.close();
}
}
});

return ids.get(0);
}
}


And I get exeption:



java.lang.ClassCastException: oracle.jdbc.driver.OracleDatabaseMetaData cannot be cast to org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo









share|improve this question
























  • Possible duplicate of get next sequence value from database using hibernate
    – aurelius
    Nov 9 at 8:19










  • @aurelius can you read my question more carefully? Specifically, point 3 and see the link that I gave
    – ip696
    Nov 9 at 8:21










  • Point 3 also shows a method for hibernate 4. And using the dialect IS a good approach. (at least this is how we do and this works fine).
    – StephaneM
    Nov 9 at 8:41










  • But I use hibernate5. Thank you for sharing your information about using this approach. I also wanted to learn other approaches.
    – ip696
    Nov 9 at 8:45













up vote
3
down vote

favorite









up vote
3
down vote

favorite











How can I get sequence nextval in JPA or Hibernate 5 by sequence name?



I have sequence the following TEST_SEQ in Oracle DB and ANOTHER_NAME_SEQ in Postgresql DB.



I need a method with following signature



public Long getSequenceByName(String sequenceName){}


And when I call this method it must return nextval from DB which is now used.



I have a couple of ideas, but they are not suitable.



1) Store native query for each DB in properties and write method like this:



@Value("${query}")//"SELECT {name}.NEXTVAL FROM DUAL"
private StringQuery;

public Long getSequenceByName(String sequenceName){
uery q = em.createNativeQuery(StringQuery.replace("{name}", sequenceName));
return (java.math.BigDecimal) q.getSingleResult();
}


But I need to store the query string with placeholders and replace placeholder to sequence name, store query for each DB.



2) Create entity with only one field @Id. Insert entity and getId(sequence value).



But if in different DB is different sequence names - ???



3) Use this. But It for hibernate 3 and I don't know if this is a good approach.



EDIT:



I try this solution:



@Component
public class SequenseRepository {

@PersistenceContext
private EntityManager em;

@Transactional
public Long getID(final String sequenceName) {
final List<Long> ids = new ArrayList<>(1);

Session session = em.unwrap(Session.class);
session.doWork(connection -> {
DialectResolver dialectResolver = new StandardDialectResolver();
Dialect dialect = dialectResolver.resolveDialect((DialectResolutionInfo) connection.getMetaData());
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
preparedStatement = connection.prepareStatement( dialect.getSequenceNextValString(sequenceName));
resultSet = preparedStatement.executeQuery();
resultSet.next();
ids.add(resultSet.getLong(1));
}catch (SQLException e) {
throw e;
} finally {
if(preparedStatement != null) {
preparedStatement.close();
}
if(resultSet != null) {
resultSet.close();
}
}
});

return ids.get(0);
}
}


And I get exeption:



java.lang.ClassCastException: oracle.jdbc.driver.OracleDatabaseMetaData cannot be cast to org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo









share|improve this question















How can I get sequence nextval in JPA or Hibernate 5 by sequence name?



I have sequence the following TEST_SEQ in Oracle DB and ANOTHER_NAME_SEQ in Postgresql DB.



I need a method with following signature



public Long getSequenceByName(String sequenceName){}


And when I call this method it must return nextval from DB which is now used.



I have a couple of ideas, but they are not suitable.



1) Store native query for each DB in properties and write method like this:



@Value("${query}")//"SELECT {name}.NEXTVAL FROM DUAL"
private StringQuery;

public Long getSequenceByName(String sequenceName){
uery q = em.createNativeQuery(StringQuery.replace("{name}", sequenceName));
return (java.math.BigDecimal) q.getSingleResult();
}


But I need to store the query string with placeholders and replace placeholder to sequence name, store query for each DB.



2) Create entity with only one field @Id. Insert entity and getId(sequence value).



But if in different DB is different sequence names - ???



3) Use this. But It for hibernate 3 and I don't know if this is a good approach.



EDIT:



I try this solution:



@Component
public class SequenseRepository {

@PersistenceContext
private EntityManager em;

@Transactional
public Long getID(final String sequenceName) {
final List<Long> ids = new ArrayList<>(1);

Session session = em.unwrap(Session.class);
session.doWork(connection -> {
DialectResolver dialectResolver = new StandardDialectResolver();
Dialect dialect = dialectResolver.resolveDialect((DialectResolutionInfo) connection.getMetaData());
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
preparedStatement = connection.prepareStatement( dialect.getSequenceNextValString(sequenceName));
resultSet = preparedStatement.executeQuery();
resultSet.next();
ids.add(resultSet.getLong(1));
}catch (SQLException e) {
throw e;
} finally {
if(preparedStatement != null) {
preparedStatement.close();
}
if(resultSet != null) {
resultSet.close();
}
}
});

return ids.get(0);
}
}


And I get exeption:



java.lang.ClassCastException: oracle.jdbc.driver.OracleDatabaseMetaData cannot be cast to org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo






java hibernate jpa sequence






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 9 at 9:07

























asked Nov 9 at 7:57









ip696

1,09711135




1,09711135












  • Possible duplicate of get next sequence value from database using hibernate
    – aurelius
    Nov 9 at 8:19










  • @aurelius can you read my question more carefully? Specifically, point 3 and see the link that I gave
    – ip696
    Nov 9 at 8:21










  • Point 3 also shows a method for hibernate 4. And using the dialect IS a good approach. (at least this is how we do and this works fine).
    – StephaneM
    Nov 9 at 8:41










  • But I use hibernate5. Thank you for sharing your information about using this approach. I also wanted to learn other approaches.
    – ip696
    Nov 9 at 8:45


















  • Possible duplicate of get next sequence value from database using hibernate
    – aurelius
    Nov 9 at 8:19










  • @aurelius can you read my question more carefully? Specifically, point 3 and see the link that I gave
    – ip696
    Nov 9 at 8:21










  • Point 3 also shows a method for hibernate 4. And using the dialect IS a good approach. (at least this is how we do and this works fine).
    – StephaneM
    Nov 9 at 8:41










  • But I use hibernate5. Thank you for sharing your information about using this approach. I also wanted to learn other approaches.
    – ip696
    Nov 9 at 8:45
















Possible duplicate of get next sequence value from database using hibernate
– aurelius
Nov 9 at 8:19




Possible duplicate of get next sequence value from database using hibernate
– aurelius
Nov 9 at 8:19












@aurelius can you read my question more carefully? Specifically, point 3 and see the link that I gave
– ip696
Nov 9 at 8:21




@aurelius can you read my question more carefully? Specifically, point 3 and see the link that I gave
– ip696
Nov 9 at 8:21












Point 3 also shows a method for hibernate 4. And using the dialect IS a good approach. (at least this is how we do and this works fine).
– StephaneM
Nov 9 at 8:41




Point 3 also shows a method for hibernate 4. And using the dialect IS a good approach. (at least this is how we do and this works fine).
– StephaneM
Nov 9 at 8:41












But I use hibernate5. Thank you for sharing your information about using this approach. I also wanted to learn other approaches.
– ip696
Nov 9 at 8:45




But I use hibernate5. Thank you for sharing your information about using this approach. I also wanted to learn other approaches.
– ip696
Nov 9 at 8:45












1 Answer
1






active

oldest

votes

















up vote
2
down vote













I found solution thanks to this article enter link description here



    public interface SequenceRepository {
int getNext(String sequenceName);
}


and implementation for each DB:



@Profile("oracle")
@Component("oracleSequenceRepository")
public class OracleSequenceRepository implements SequenceRepository{

private final DataSource dataSource;

@Autowired
public OracleSequenceRepository(@Qualifier("dataSource") DataSource dataSource) {
this.dataSource = dataSource;
}

@Transactional(readOnly = true)
@Override
public int getNext(String sequenceName) {
AbstractSequenceMaxValueIncrementer incr = new OracleSequenceMaxValueIncrementer(this.dataSource, sequenceName);
return incr.nextIntValue();
}
}


and



@Profile("postgre")
@Component("postgresSequenceRepository")
public class PostgreSequenceRepository implements SequenceRepository{

private final DataSource dataSource;

@Autowired
public PostgreSequenceRepository(@Qualifier("dataSource") DataSource dataSource) {
this.dataSource = dataSource;
}

@Transactional(readOnly = true)
@Override
public int getNext(String sequenceName) {
AbstractSequenceMaxValueIncrementer incr = new PostgresSequenceMaxValueIncrementer(this.dataSource, sequenceName);
return incr.nextIntValue();
}
}





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',
    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%2f53221799%2fjpa-hibernate5-get-sequence-nextval-by-sequence-name%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    2
    down vote













    I found solution thanks to this article enter link description here



        public interface SequenceRepository {
    int getNext(String sequenceName);
    }


    and implementation for each DB:



    @Profile("oracle")
    @Component("oracleSequenceRepository")
    public class OracleSequenceRepository implements SequenceRepository{

    private final DataSource dataSource;

    @Autowired
    public OracleSequenceRepository(@Qualifier("dataSource") DataSource dataSource) {
    this.dataSource = dataSource;
    }

    @Transactional(readOnly = true)
    @Override
    public int getNext(String sequenceName) {
    AbstractSequenceMaxValueIncrementer incr = new OracleSequenceMaxValueIncrementer(this.dataSource, sequenceName);
    return incr.nextIntValue();
    }
    }


    and



    @Profile("postgre")
    @Component("postgresSequenceRepository")
    public class PostgreSequenceRepository implements SequenceRepository{

    private final DataSource dataSource;

    @Autowired
    public PostgreSequenceRepository(@Qualifier("dataSource") DataSource dataSource) {
    this.dataSource = dataSource;
    }

    @Transactional(readOnly = true)
    @Override
    public int getNext(String sequenceName) {
    AbstractSequenceMaxValueIncrementer incr = new PostgresSequenceMaxValueIncrementer(this.dataSource, sequenceName);
    return incr.nextIntValue();
    }
    }





    share|improve this answer



























      up vote
      2
      down vote













      I found solution thanks to this article enter link description here



          public interface SequenceRepository {
      int getNext(String sequenceName);
      }


      and implementation for each DB:



      @Profile("oracle")
      @Component("oracleSequenceRepository")
      public class OracleSequenceRepository implements SequenceRepository{

      private final DataSource dataSource;

      @Autowired
      public OracleSequenceRepository(@Qualifier("dataSource") DataSource dataSource) {
      this.dataSource = dataSource;
      }

      @Transactional(readOnly = true)
      @Override
      public int getNext(String sequenceName) {
      AbstractSequenceMaxValueIncrementer incr = new OracleSequenceMaxValueIncrementer(this.dataSource, sequenceName);
      return incr.nextIntValue();
      }
      }


      and



      @Profile("postgre")
      @Component("postgresSequenceRepository")
      public class PostgreSequenceRepository implements SequenceRepository{

      private final DataSource dataSource;

      @Autowired
      public PostgreSequenceRepository(@Qualifier("dataSource") DataSource dataSource) {
      this.dataSource = dataSource;
      }

      @Transactional(readOnly = true)
      @Override
      public int getNext(String sequenceName) {
      AbstractSequenceMaxValueIncrementer incr = new PostgresSequenceMaxValueIncrementer(this.dataSource, sequenceName);
      return incr.nextIntValue();
      }
      }





      share|improve this answer

























        up vote
        2
        down vote










        up vote
        2
        down vote









        I found solution thanks to this article enter link description here



            public interface SequenceRepository {
        int getNext(String sequenceName);
        }


        and implementation for each DB:



        @Profile("oracle")
        @Component("oracleSequenceRepository")
        public class OracleSequenceRepository implements SequenceRepository{

        private final DataSource dataSource;

        @Autowired
        public OracleSequenceRepository(@Qualifier("dataSource") DataSource dataSource) {
        this.dataSource = dataSource;
        }

        @Transactional(readOnly = true)
        @Override
        public int getNext(String sequenceName) {
        AbstractSequenceMaxValueIncrementer incr = new OracleSequenceMaxValueIncrementer(this.dataSource, sequenceName);
        return incr.nextIntValue();
        }
        }


        and



        @Profile("postgre")
        @Component("postgresSequenceRepository")
        public class PostgreSequenceRepository implements SequenceRepository{

        private final DataSource dataSource;

        @Autowired
        public PostgreSequenceRepository(@Qualifier("dataSource") DataSource dataSource) {
        this.dataSource = dataSource;
        }

        @Transactional(readOnly = true)
        @Override
        public int getNext(String sequenceName) {
        AbstractSequenceMaxValueIncrementer incr = new PostgresSequenceMaxValueIncrementer(this.dataSource, sequenceName);
        return incr.nextIntValue();
        }
        }





        share|improve this answer














        I found solution thanks to this article enter link description here



            public interface SequenceRepository {
        int getNext(String sequenceName);
        }


        and implementation for each DB:



        @Profile("oracle")
        @Component("oracleSequenceRepository")
        public class OracleSequenceRepository implements SequenceRepository{

        private final DataSource dataSource;

        @Autowired
        public OracleSequenceRepository(@Qualifier("dataSource") DataSource dataSource) {
        this.dataSource = dataSource;
        }

        @Transactional(readOnly = true)
        @Override
        public int getNext(String sequenceName) {
        AbstractSequenceMaxValueIncrementer incr = new OracleSequenceMaxValueIncrementer(this.dataSource, sequenceName);
        return incr.nextIntValue();
        }
        }


        and



        @Profile("postgre")
        @Component("postgresSequenceRepository")
        public class PostgreSequenceRepository implements SequenceRepository{

        private final DataSource dataSource;

        @Autowired
        public PostgreSequenceRepository(@Qualifier("dataSource") DataSource dataSource) {
        this.dataSource = dataSource;
        }

        @Transactional(readOnly = true)
        @Override
        public int getNext(String sequenceName) {
        AbstractSequenceMaxValueIncrementer incr = new PostgresSequenceMaxValueIncrementer(this.dataSource, sequenceName);
        return incr.nextIntValue();
        }
        }






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 9 at 10:47

























        answered Nov 9 at 9:49









        ip696

        1,09711135




        1,09711135






























            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.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • 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%2f53221799%2fjpa-hibernate5-get-sequence-nextval-by-sequence-name%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







            這個網誌中的熱門文章

            Xamarin.form Move up view when keyboard appear

            Post-Redirect-Get with Spring WebFlux and Thymeleaf

            JBPM : POST request for execute process go wrong