Как я могу получить sequence nextval
в JPA
или Hibernate 5
на sequence name
?
У меня есть последовательность, следующая TEST_SEQ
в Oracle
DB и ANOTHER_NAME_SEQ
в Postgresql
DB.
Мне нужен метод со следующей подписью
public Long getSequenceByName(String sequenceName){}
И когда я вызываю этот метод, он должен вернуть nextval
из БД, которая сейчас используется.
У меня есть пара идей, но они не подходят.
1) Сохраните собственный запрос для каждой БД в свойствах и напишите метод следующим образом:
@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();
}
Но мне нужно сохранить строку запроса с заполнителями и заменить заполнитель на имя последовательности, сохранить запрос для каждой БД.
2) Создать сущность только с одним полем @Id
. Вставьте сущность и getId (значение последовательности).
Но если в разных БД есть разные имена последовательностей - ???
3) Используйте this . Но это для hibernate 3, и я не знаю, хороший ли это подход.
EDIT:
Я пробую это решение:
@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);
}
}
И я получаю исключение:
java.lang.ClassCastException: oracle.jdbc.driver.OracleDatabaseMetaData cannot be cast to org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo