Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/305.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JPA/Hibernate5按序列名称获取序列nextval_Java_Hibernate_Jpa_Sequence - Fatal编程技术网

Java JPA/Hibernate5按序列名称获取序列nextval

Java JPA/Hibernate5按序列名称获取序列nextval,java,hibernate,jpa,sequence,Java,Hibernate,Jpa,Sequence,如何在JPA或hibernate5中通过sequencename获取sequencenextval 我在OracleDB和PostgresqlDB中对以下TEST\u SEQ进行了排序 我需要一个具有以下签名的方法 public Long getSequenceByName(String sequenceName){} 当我调用这个方法时,它必须从现在使用的DB返回nextval 我有一些想法,但不适合 1) 在properties中存储每个DB的本机查询,并按如下方式写入方法: @Value

如何在
JPA
hibernate5
中通过
sequencename
获取
sequencenextval

我在
Oracle
DB和
Postgresql
DB中对以下
TEST\u SEQ
进行了排序

我需要一个具有以下签名的方法

public Long getSequenceByName(String sequenceName){}
当我调用这个方法时,它必须从现在使用的DB返回
nextval

我有一些想法,但不适合

1) 在properties中存储每个DB的本机查询,并按如下方式写入方法:

@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) 使用。但它适用于Hibernate3,我不知道这是否是一个好方法

编辑:

我尝试以下解决方案:

@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);
    }
}

多亏了这篇文章,我找到了解决方案

每个数据库的配置和实现:

@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();
    }
}


@aurelius的可能副本你能更仔细地阅读我的问题吗?具体来说,第3点和我提供的链接第3点也显示了hibernate 4的方法。使用方言是一种很好的方法。(至少我们是这样做的,而且效果很好)但我使用hibernate5。感谢您分享有关使用此方法的信息。我还想学习其他方法。
    public interface SequenceRepository {
    int getNext(String sequenceName);
   }
@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();
    }
}
@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();
    }
}