Есть проект на SpringIntegration. На jpa:outbound-channel-adapter поступают jpa сущности, которые должны персиститься в БД, если не существует записи с таким Id. Если Id существует, то обновить поля в БД, которые в сущности не пустые (не null). В текущей реализации при обновлении поля, сущности которые равны null заменяют нулами данные в БД. Как их правильно соеденить? Возможно ли это сделать из коробки, средствами Spring Integration JPA, не создавая свой service-activator?
<int-jpa:outbound-channel-adapter
channel="VCardPersistChannel"
persist-mode="MERGE"
entity-class="entities.blocks.jpa.SendRequestEntity"
entity-manager-factory="externalEntityManagerfactory">
<int-jpa:transactional transaction-manager="txManager" />
</int-jpa:outbound-channel-adapter>
Сущность:
@Entity(name = "SendRequestEntity")
@Table(name = "ITX_PT_SEND_REQUEST")
@DynamicUpdate(value=true)
@SelectBeforeUpdate(value=true)
public class SendRequestEntity {
@Column
@Id
private String requestId;
@Column
private String userId;
@Column
private String bindingId;
@Column
private String clientBlockId;
@Column
private String blockId;
@Column
private String blockType;
@Column
private Integer reasonId;
@Column(name = "DATE_SEND")
@Temporal(TemporalType.TIMESTAMP)
private Date dateSend;
@Column
private String ewExtErrorCode;
@Column
private String callbackRequestId;
@Column
private String callbackBlockId;
@Column
@Temporal(TemporalType.TIMESTAMP)
private Date occurredOn;
@Column(name = "DATE_CALLBACK")
@Temporal(TemporalType.TIMESTAMP)
private Date dateCallback;
@Column
private String errorCode;
@Column
private String errorDesc;
@Column(name = "DATE_NOTIFICATION")
@Temporal(TemporalType.TIMESTAMP)
private Date dateNotification;
//Getter - setters
}
}
Задача решилась запиливанием собственного ServiceActivator
public class SendRequestMerger {
private EntityManager entityManager;
public SendRequestMerger(EntityManagerFactory entityManagerFactory) {
entityManager = entityManagerFactory.createEntityManager();
}
@ServiceActivator
public SendRequestEntity handleMessage(@SuppressWarnings("rawtypes") Message message) throws IllegalArgumentException, IllegalAccessException{
SendRequestEntity updateSendRequest = (SendRequestEntity)message.getPayload();
SendRequestEntity currentSendRequest = entityManager.find(SendRequestEntity.class, updateSendRequest.getRequestId());
if (currentSendRequest == null) {
System.out.println("currentSendRequest is null");
return updateSendRequest;
}
Field[] fields = SendRequestEntity.class.getDeclaredFields();
for(Field field: fields){
field.setAccessible(true);
if (field.get(updateSendRequest) != null ) {
field.set(currentSendRequest, field.get(updateSendRequest));
}
}
return currentSendRequest;
}
public void destroy(){
entityManager.close();
}
}
XML:
<!-- Мержим сущность -->
<integration:channel id="VCardPersistChannel" />
<integration:service-activator
ref="sendRequestEnricher"
input-channel="VCardPersistChannel"
output-channel="VCardPersistMergedChannel"/>
<bean id="sendRequestEnricher"
class="handlers.SendRequestMerger"
destroy-method="destroy">
<constructor-arg ref="externalEntityManagerfactory"/>
</bean>
<!-- Персист в БД -->
<integration:channel id="VCardPersistMergedChannel" />
<int-jpa:outbound-channel-adapter
channel="VCardPersistMergedChannel"
persist-mode="MERGE"
entity-class="entities.blocks.jpa.SendRequestEntity"
entity-manager-factory="externalEntityManagerfactory">
<int-jpa:transactional transaction-manager="txManager" />
</int-jpa:outbound-channel-adapter>
Оборудование для ресторана: новинки профессиональной кухонной техники
Частный дом престарелых в Киеве: комфорт, забота и профессиональный уход
Читаю Spring in action 5, пытаюсь реализовать примерыНа одном из контроллеров выходит ошибка: