Issue
I'm implementing Transactional Outbox pattern using Java. The Message Relay Service will poll the Outbox table for entries, and after an outbox message is found and processed it will update the Outbox entry.
Question is, how do I set the parameter from MessagingGateway to the Jpa Query?
@Bean
public JpaExecutor jpaUpdateStateExecutor() {
JpaExecutor jpaExecutor = new JpaExecutor(this.entityManagerFactory);
jpaExecutor.setNamedQuery("myQuery");
jpaExecutor.setUsePayloadAsParameterSource(true);
jpaExecutor.setExpectSingleResult(true);
return jpaExecutor;
}
@Bean
@ServiceActivator(inputChannel = "jpaChannel")
public MessageHandler jpaOutbound() {
JpaOutboundGateway gateway = new JpaOutboundGateway(jpaUpdateStateExecutor());
gateway.setGatewayType(OutboundGatewayType.UPDATING);
return gateway;
}
My Gateway:
@MessagingGateway
public interface MyGateway {
@Gateway(requestChannel = "jpaChannel")
@Transactional
void jpaActions(Long idOfEntity);
}
My domain object:
@Entity
@Getter
@Setter
@ToString
@NoArgsConstructor
@Table
@NamedQuery(name = "myQuery", query = "UPDATE MyTable SET state = 'PROCESSED' WHERE id = :id")
public class Outbox {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private Long id;
private String state;
}
Solution
It would be great to see your query and how you'd like to have that Long idOfEntity
to be mapped to some query param.
The doc for that setUsePayloadAsParameterSource
looks like this:
use-payload-as-parameter-source
If set to true, the payload of the Message is used as a source for parameters. If set to false, the entire Message is available as a source for parameters. If no JPA Parameters are passed in, this property defaults to true. This means that, if you use a default
BeanPropertyParameterSourceFactory
, the bean properties of the payload are used as a source for parameter values for the JPA query. However, if JPA Parameters are passed in, this property, by default, evaluates to false. The reason is that JPA Parameters let you provide SpEL Expressions. Therefore, it is highly beneficial to have access to the entire Message, including the headers. Optional.
Perhaps you'd prefer to have that option as false
and then in your query you could use a param for that idOfEntity
as just a :payload
placeholder.
Answered By - Artem Bilan
Answer Checked By - Pedro (JavaFixing Volunteer)