Spring Intergration JPA. Обновление сущности в БД

152
31 мая 2019, 03:30

Есть проект на 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      
    }   
}
Answer 1

Задача решилась запиливанием собственного 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>
READ ALSO
Ошибка в доступе к открытому методу закрытой переменной

Ошибка в доступе к открытому методу закрытой переменной

Повторяю в точности код из книги Шилдта

127
JAVA - как собирается .jar?

JAVA - как собирается .jar?

Подскажите "обывателю" пожалуйста какой мой ход действий

131
Cannot convert value of type &#39;java.lang.String&#39;

Cannot convert value of type 'java.lang.String'

Читаю Spring in action 5, пытаюсь реализовать примерыНа одном из контроллеров выходит ошибка:

140
unexpected token, identifier expected

unexpected token, identifier expected

Что я пропустил в коде?

113