Reputation: 977
I'm trying to use a Hibernate JPA repository method as the method for a service-activator. The definition within the chain looks like the following.
<int:chain input-channel="bootstrapLineupCdsStart" output-channel="bootstrapLineupItemCdsStart">
<int:service-activator ref="lineupRepository" method="findByIntegrationStatusNew" />
<int:filter expression="!payload.isEmpty()" discard-channel="bootstrapLineupItemCdsStart"/>
<int:splitter expression="payload"/>
<int:service-activator ref="lineupServicePipeline" method="createLineup"/>
<int:aggregator/>
</int:chain>
The offending line is the first service-activator, specifically this line <int:service-activator ref="lineupRepository" method="findByIntegrationStatusNew" />
For the sake of completeness here is the repository class itself
@Repository( "lineupRepository" )
public interface LineupRepository extends JpaRepository<LineupEntity, Integer> {
@Query("select l from LineupEntity l where l.integrationStatus = 0")
List<LineupEntity> findByIntegrationStatusNew();
}
Now because of the magic of spring/hibernate I don't actually implement the findByIntegrationStatusNew myself; this is dynamically implemented by the framework at runtime. I also don't need to explicitly define the lineupRepository bean as the @Repository annotation handles this for me.
As a result of the above I get the following exeption.
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.integration.handler.MessageHandlerChain#9$child#0.handler': FactoryBean threw exception on object creation; nested exception is java.lang.IllegalArgumentException: Target object of type [class com.sun.proxy.$Proxy79] has no eligible methods for handling Messages.
Finally, I do have a work around in place that seems to get the job done; it is an obvious work around and I suspect shouldn't be necessary. The work around consists of creating a new bean, explicitly defining the bean in the context XML and calling that method instead of the method on repository. So my work around looks a bit like this; first the workaround's context looks like this instead.
<int:chain input-channel="bootstrapLineupCdsStart" output-channel="bootstrapLineupItemCdsStart">
<int:service-activator ref="lineupRepositoryService" method="findByIntegrationStatusNew" />
<int:filter expression="!payload.isEmpty()" discard-channel="bootstrapLineupItemCdsStart"/>
<int:splitter expression="payload"/>
<int:service-activator ref="lineupServicePipeline" method="createLineup"/>
<int:aggregator/>
</int:chain>
<bean id="lineupRepositoryService" class="com.mypackage.LineupRepositoryService"/>
Notice the first service-activator now references LineupRepositoryService instead of LineupRepository, and I also added a new bean definition.
Second in the work around, of course, I also defined a LineupRespositoryService class that looks like the following.
public class LineupRepositoryService {
@Autowired
private LineupRepository lineupRepository;
public List<LineupEntity> findByIntegrationStatusNew() {
return lineupRepository.findByIntegrationStatusNew();
}
}
The workaround works, but I'd rather do it the right way. So anyone know how I can get it to properly work or what is going on here?
Upvotes: 1
Views: 714
Reputation: 121552
@JeffreyPhillipsFreeman, we confirm with the test-cases that it is an issue from Spring Integration reflection method invocation perspective.
Need to fix it anyway: https://jira.spring.io/browse/INT-3820.
Mean while there is only a workaround like your service wrapper
.
Upvotes: 1