Java 在分区表中插入时获取生成的键值

Java 在分区表中插入时获取生成的键值,java,postgresql,spring-jdbc,Java,Postgresql,Spring Jdbc,嗨,我在Postgres有一张桌子,比如说电子邮件。它是分区的,因此无论我使用java应用程序执行什么插入操作,都不会影响主表,因为数据实际上是插入到子表中的。问题是,我想得到一个自动生成的列值(比如email\u message\u id,它是大的串行类型)。Postgres将其返回为null,因为主表上没有插入操作。对于oracle,我使用GeneratedKeyHolder来获取该值。但我无法对postgres中的分区表执行相同的操作。请帮帮我 下面是我们用于oracle的代码片段 pub

嗨,我在Postgres有一张桌子,比如说电子邮件。它是分区的,因此无论我使用java应用程序执行什么插入操作,都不会影响主表,因为数据实际上是插入到子表中的。问题是,我想得到一个自动生成的列值(比如email\u message\u id,它是大的串行类型)。Postgres将其返回为null,因为主表上没有插入操作。对于oracle,我使用GeneratedKeyHolder来获取该值。但我无法对postgres中的分区表执行相同的操作。请帮帮我

下面是我们用于oracle的代码片段

public void createAndFetchPKImpl(final Entity pEntity,
  final String pStatementId, final String pPKColumnName) {


final SqlParameterSource parameterSource =
  new BeanPropertySqlParameterSource(pEntity);

  final String[] columnNames = new String[]{"email_message_id"};
  final KeyHolder keyHolder = new GeneratedKeyHolder();
  final int numberOfRowsEffected = mNamedParameterJdbcTemplate.update(
      getStatement(pStatementId), parameterSource, keyHolder, columnNames);
  pEntity.setId(ConversionUtil.getLongValue(keyHolder.getKey()));

}

在PostgreSQL中使用基于触发器的分区时,JDBC驱动程序报告零行受影响/插入是正常的。这是因为原始SQL
UPDATE
INSERT
DELETE
实际上没有生效,主表上没有任何行被更改。而是对一个或多个子表执行操作

基本上,PostgreSQL中的分区有点麻烦,这是它的一个更明显的限制

解决办法是:

  • 插入
    /
    更新
    /
    删除
    直接针对子表,而不是顶级表
  • 忽略结果行计数;或
  • 使用
    规则
    s和
    插入。。。返回
    (但它们有自己的问题)(不适用于分区)

“GeneratedKeyHolder”表示您可能正在使用Spring,但我们不必猜测。请详细说明。JDBC驱动程序版本,任何更高级别的抽象,如JPA/Spring,映射代码等。是的,我们使用的是SpringJDBC版本3.1.1。Postgres版本为8.1我得到numberofrowseffect为零,keyHolder.getKey()为null,即使插入正在表中进行。好的,第一件事:你昨天需要升级PostgreSQL,8.1不受支持且已过时。它可能无法修补将于4月4日修复的重大安全问题:我尝试使用“RETURNING currval('email_messages_email_message_id_seq')插入,但仍然无法获得该值。但是,我可以通过使用用于插入的存储过程来实现它。您能指定我如何使用返回值来获取值吗clause@user1495565您使用的是基于规则的分区还是基于触发器的分区?如果我使用规则而不是触发器(当前代码)更改分区,根据postgres当前的实现,它只允许无条件的instead规则包含返回;此外,同一事件的所有规则中最多可以有一个RETURNING子句。所以我不能从所有规则中返回值,因为我对同一个表有多个分区。@mohansammeta啊,好的,我忘了这一点。因此,你基本上必须在应用层中根据前两点来解决这个问题。触发器是做什么的?如果它将相同的记录插入主表,它可以检索其主id,而主id又可以通过Java方法调用传递。