使用JdbcPagingItemReader导致连接语句导致MySQLIntegrityConstraintViolationException

时间:2015-03-11 14:57:00

标签: spring-batch

我正在运行Spring Batch并使用JdbcPagingItemReader。使用以下示例配置:

<bean id="dogQueryProvider"		class="org.springframework.batch.item.database.support.SqlPagingQueryProviderFactoryBean">
		<property name="databaseType" value="mysql" />
		<property name="dataSource" ref="dataSource" />
		<property name="selectClause"
			value="SELECT owner.id as ownerid, first_name, last_name, dog_name " />
		<property name="fromClause"
			value="FROM dog_owner owner INNER JOIN dog ON owner.id = dog.id " />
		<property name="sortKey" value="owner.id" />
</bean>

我收到与以下相关的错误:

  

order order子句中的列'id'不明确;嵌套异常是com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException:order子句中的列'id'是不明确的。

认为dog_ownerdog表有id列。我认为这与AbstractSqlPagingQueryProvider.getSortKeysWithoutAliases有关,我认为owner从指定为owner.id的{​​{1}}中删除sortKey。有什么建议可以解决这个问题吗?

3 个答案:

答案 0 :(得分:2)

显然,这似乎仍然以某种形式发生,但有办法制作您的查询,以便别名不会被删除。您可以通过选择具有不同名称的列来重命名已连接的列。

您的selectClause变为

SELECT owner.id, owner.first_name, owner.last_name, dog.dog_name

FromClause成为

      FROM dog_owner owner
INNER JOIN (SELECT d2.id AS dogId, d2.dog_name
              FROM dog d2) AS dog
        ON owner.id = dog.dogId

现在你应该能够使用“id”作为sortKey,因为只有一列名为“id”。即使您将dog.dogId添加到selectClause中,这也可以。

答案 1 :(得分:1)

你在为什么会发生这种情况的原因是正确的。在您的情况下,我希望使用您的别名来解决问题。因此,您将owner.id别名为ownerid,但是您不在sortkey字段中使用它(或者就此而言是连接子句)。使用别名,你应该没问题。

答案 2 :(得分:0)

我们遇到了这个问题,Spring必须从返回的结果集中获取排序键才能正确分页。在幕后,将在WHERE子句中使用sort键,该键不适用于列别名,因为WHERE在数据库级别的SELECT语句之前被处理。

我们的解决方案是使用SELECT owner.id as "owner.id",以便可以使用相同的名称从结果集中检索排序关键字。进行SELECT owner.id会将列id放入结果集中,这会导致列不明确的问题。对于上一个答案的嵌套查询,我们更喜欢这种方法。