Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/flutter/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Hibernate MessageProcessor在处理时释放值->;InvalidInputException:重复密钥,电影Id:333,评论Id:0_Hibernate_Spring Boot_Apache Kafka_Rabbitmq_Microservices - Fatal编程技术网

Hibernate MessageProcessor在处理时释放值->;InvalidInputException:重复密钥,电影Id:333,评论Id:0

Hibernate MessageProcessor在处理时释放值->;InvalidInputException:重复密钥,电影Id:333,评论Id:0,hibernate,spring-boot,apache-kafka,rabbitmq,microservices,Hibernate,Spring Boot,Apache Kafka,Rabbitmq,Microservices,我正在使用一组简单的微服务,在消息处理和保存值的过程中发生了两件奇怪的事情 review_1 | 2020-01-29 16:55:52.867 ERROR 1 --- [.reviewsGroup-1] o.s.integration.handler.LoggingHandler : org.springframework.messaging.MessagingException: Exception thrown while invoking com.geborski

我正在使用一组简单的微服务,在消息处理和保存值的过程中发生了两件奇怪的事情

review_1           | 2020-01-29 16:55:52.867 ERROR 1 --- [.reviewsGroup-1] o.s.integration.handler.LoggingHandler   : org.springframework.messaging.MessagingException: Exception thrown while invoking com.geborskimateusz.microservices.core.review.service.MessageProcessor#process[1 args]; nested exception is com.geborskimateusz.util.exceptions.InvalidInputException: Duplicate key, Movie Id: 333, Review Id:0, failedMessage=GenericMessage [payload=byte[197], headers={amqp_receivedDeliveryMode=PERSISTENT, amqp_receivedExchange=reviews, amqp_deliveryTag=3, deliveryAttempt=3, amqp_consumerQueue=reviews.reviewsGroup, amqp_redelivered=false, amqp_receivedRoutingKey=reviews, amqp_timestamp=Wed Jan 29 16:55:49 GMT 2020, amqp_messageId=95b4bae5-b5ab-12a1-462a-567252c04778, id=b88df7f0-b6ad-b26b-5280-a80a4396efd7, amqp_consumerTag=amq.ctag-NcAue9uq8t8rQC_EmY9cZQ, contentType=application/json, timestamp=1580316951325}]
review_1           |    at org.springframework.cloud.stream.binding.StreamListenerMessageHandler.handleRequestMessage(StreamListenerMessageHandler.java:63)
review_1           |    at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:123)
review_1           |    at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:162)
review_1           |    at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:115)
review_1           |    at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:133)
review_1           |    at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:106)
review_1           |    at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:73)
review_1           |    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:451)
review_1           |    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:400)
review_1           |    at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:187)
review_1           |    at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:166)
review_1           |    at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:47)
review_1           |    at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:109)
review_1           |    at org.springframework.integration.endpoint.MessageProducerSupport.sendMessage(MessageProducerSupport.java:203)
review_1           |    at org.springframework.integration.amqp.inbound.AmqpInboundChannelAdapter.access$1100(AmqpInboundChannelAdapter.java:58)
review_1           |    at org.springframework.integration.amqp.inbound.AmqpInboundChannelAdapter$Listener.lambda$onMessage$0(AmqpInboundChannelAdapter.java:211)
review_1           |    at org.springframework.retry.support.RetryTemplate.doExecute(RetryTemplate.java:287)
review_1           |    at org.springframework.retry.support.RetryTemplate.execute(RetryTemplate.java:180)
review_1           |    at org.springframework.integration.amqp.inbound.AmqpInboundChannelAdapter$Listener.onMessage(AmqpInboundChannelAdapter.java:208)
review_1           |    at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:1477)
review_1           |    at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.actualInvokeListener(AbstractMessageListenerContainer.java:1400)
review_1           |    at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:1387)
review_1           |    at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:1366)
review_1           |    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.doReceiveAndExecute(SimpleMessageListenerContainer.java:848)
review_1           |    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.receiveAndExecute(SimpleMessageListenerContainer.java:832)
review_1           |    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$700(SimpleMessageListenerContainer.java:78)
review_1           |    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1073)
review_1           |    at java.base/java.lang.Thread.run(Thread.java:835)
review_1           | Caused by: com.geborskimateusz.util.exceptions.InvalidInputException: Duplicate key, Movie Id: 333, Review Id:0
review_1           |    at com.geborskimateusz.microservices.core.review.service.BaseReviewService.createReview(BaseReviewService.java:58)
review_1           |    at com.geborskimateusz.microservices.core.review.service.MessageProcessor.process(MessageProcessor.java:34)
review_1           |    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
review_1           |    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
review_1           |    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
review_1           |    at java.base/java.lang.reflect.Method.invoke(Method.java:567)
review_1           |    at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:189)
review_1           |    at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:119)
review_1           |    at org.springframework.cloud.stream.binding.StreamListenerMessageHandler.handleRequestMessage(StreamListenerMessageHandler.java:55)
review_1           |    ... 27 more
首先,当我准备通过message reviewId发送对象时,它等于某个值,例如437,当消息处理器接收到消息时,该值以某种方式丢失,且仅为0,我将用代码和日志表示它:

将发送消息的方法如下所示:

 @Override
    public Review createReview(Review review) {
        log.info("MovieCompositeIntegration.createReview(Review review), passed argument: {}", review.toString());

        messageSources.outputReviews()
                .send(MessageBuilder.withPayload(
                        new Event<>(Event.Type.CREATE, review.getMovieId(), review)
                ).build());

        return review;
    } 
此方法向review microservice发送消息,其中创建事件如下所示:

@Slf4j
@EnableBinding(Sink.class)
public class MessageProcessor {

    private final ReviewService reviewService;

    public MessageProcessor(ReviewService reviewService) {
        this.reviewService = reviewService;
    }

    @StreamListener(target = Sink.INPUT)
    public void process(Event<Integer, Review> event) {

        log.info("Process message created at {}...", event.getEventCreatedAt());
        log.info("Process message body: {}", event.toString());

        switch (event.getEventType()) {

            case CREATE:
                Review review = event.getData();
                log.info("Create review with ID: {}/{}", review.getMovieId(), review.getReviewId());
                log.info(review.toString());
                reviewService.createReview(review);
                break;

            default:
                String errorMessage = "Incorrect event type: " + event.getEventType() + ", expected a CREATE or DELETE event";
                log.warn(errorMessage);
                throw new EventProcessingException(errorMessage);
        }

        log.info("Message processing done!");
    }
}
因此(可能)在保存到数据库时会引发以下错误:

review_1           | 2020-01-29 16:01:34.151 ERROR 1 --- [.reviewsGroup-1] o.s.integration.handler.LoggingHandler   : org.springframework.messaging.MessagingException: Exception thrown while invoking com.geborskimateusz.microservices.core.review.service.MessageProcessor#process[1 args]; nested exception is com.geborskimateusz.util.exceptions.InvalidInputException: Duplicate key, Movie Id: 333, Review Id:0, failedMessage=GenericMessage [payload=byte[197], headers={amqp_receivedDeliveryMode=PERSISTENT, amqp_receivedExchange=reviews, amqp_deliveryTag=2, deliveryAttempt=3, amqp_consumerQueue=reviews.reviewsGroup, amqp_redelivered=false, amqp_receivedRoutingKey=reviews, amqp_timestamp=Wed Jan 29 16:01:32 GMT 2020, amqp_messageId=b9f05c16-67a5-a823-de74-5f519f14d8b3, id=4ddedcea-3938-0e03-0ac8-536e5149f50b, amqp_consumerTag=amq.ctag-GaxrablC0mlEtccmO7yVLw, contentType=application/json, timestamp=1580313692567}]
更重要的是,即使reviewId以某种方式从具体值更改为0,默认行为也应将此实体识别为新实体,但会引发异常。我错过了什么?我为此挣扎了大约一个星期,我没有主意了,任何帮助都将不胜感激。 我还附上额外的活动和审查代码:

审查:

@Getter
@Setter
@AllArgsConstructor
@Builder
public class Review {
    private final int movieId;
    private final int reviewId;
    private final String author;
    private final String subject;
    private final String content;
    private String serviceAddress;

    public Review() {
        movieId = 0;
        reviewId = 0;
        author = null;
        subject = null;
        content = null;
        serviceAddress = null;
    }

    @Override
    public String toString() {
        return "Review{" +
                "movieId=" + movieId +
                ", reviewId=" + reviewId +
                ", author='" + author + '\'' +
                ", subject='" + subject + '\'' +
                ", content='" + content + '\'' +
                ", serviceAddress='" + serviceAddress + '\'' +
                '}';
    }
} 
审查实体:

@NoArgsConstructor
@AllArgsConstructor
@Builder
@Getter
@Setter
@Entity
@Table(name = "reviews", indexes = { @Index(name = "reviews_unique_idx", unique = true, columnList = "movieId,reviewId") })
public class ReviewEntity {

    @Id
    @GeneratedValue
    private Integer id;

    @Version
    private Integer version;

    private Integer movieId;
    private Integer reviewId;
    private String author;
    private String subject;
    private String content;
    private String serviceAddress;

    public ReviewEntity(Integer movieId, Integer reviewId, String author, String subject, String content, String serviceAddress) {
        this.movieId = movieId;
        this.reviewId = reviewId;
        this.author = author;
        this.subject = subject;
        this.content = content;
        this.serviceAddress = serviceAddress;
    }
}
及活动:

@Getter
public class Event<K, T> {

    public enum Type {CREATE, DELETE}

    private Event.Type eventType;
    private K key;
    private T data;
    private LocalDateTime eventCreatedAt;

    public Event() {
        this.eventType = null;
        this.key = null;
        this.data = null;
        this.eventCreatedAt = null;
    }

    public Event(Type eventType, K key, T data) {
        this.eventType = eventType;
        this.key = key;
        this.data = data;
        this.eventCreatedAt = now();
    }

    @Override
    public String toString() {
        return "Event{" +
                "eventType=" + eventType +
                ", key=" + key +
                ", data=" + data +
                ", eventCreatedAt=" + eventCreatedAt +
                '}';
    }
}
@Getter
公开课活动{
公共枚举类型{CREATE,DELETE}
私有事件。类型eventType;
私钥;
私有T数据;
私有LocalDateTime事件创建日期;
公共活动(){
this.eventType=null;
this.key=null;
this.data=null;
this.eventCreatedAt=null;
}
公共事件(类型eventType、K键、T数据){
this.eventType=eventType;
this.key=key;
这个数据=数据;
this.eventCreatedAt=now();
}
@凌驾
公共字符串toString(){
返回“事件{”+
“eventType=“+eventType+
“,key=“+key”+
“,data=“+数据”+
,eventCreatedAt=“+eventCreatedAt+
'}';
}
}
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Getter
@Setter
@Entity
@Table(name = "reviews", indexes = { @Index(name = "reviews_unique_idx", unique = true, columnList = "movieId,reviewId") })
public class ReviewEntity {

    @Id
    @GeneratedValue
    private Integer id;

    @Version
    private Integer version;

    private Integer movieId;
    private Integer reviewId;
    private String author;
    private String subject;
    private String content;
    private String serviceAddress;

    public ReviewEntity(Integer movieId, Integer reviewId, String author, String subject, String content, String serviceAddress) {
        this.movieId = movieId;
        this.reviewId = reviewId;
        this.author = author;
        this.subject = subject;
        this.content = content;
        this.serviceAddress = serviceAddress;
    }
}
@Getter
public class Event<K, T> {

    public enum Type {CREATE, DELETE}

    private Event.Type eventType;
    private K key;
    private T data;
    private LocalDateTime eventCreatedAt;

    public Event() {
        this.eventType = null;
        this.key = null;
        this.data = null;
        this.eventCreatedAt = null;
    }

    public Event(Type eventType, K key, T data) {
        this.eventType = eventType;
        this.key = key;
        this.data = data;
        this.eventCreatedAt = now();
    }

    @Override
    public String toString() {
        return "Event{" +
                "eventType=" + eventType +
                ", key=" + key +
                ", data=" + data +
                ", eventCreatedAt=" + eventCreatedAt +
                '}';
    }
}