1

I am trying out a spring boot app using web-flux, and r2dbc for PostgreSQL, initially I could do few POST, GET, PUT, DELETE actions. However, when I tried to link customer table with subscription table, errors started to show up.

I am pasting these entity classes below here

package reactive_web_flux_example.reactive_web_flux_example.Entity;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.relational.core.mapping.Table;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Table(value = "customer")
@Data
public class Customer {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long customerId;
    private String customerName;
    private String customerEmail;
    private String customerPhone;
    @OneToMany(fetch = FetchType.EAGER, mappedBy = "customer", cascade = CascadeType.ALL)
    @JsonIgnoreProperties("customer")
    private List<Subscription> subscriptionList = new ArrayList<>();
}

package reactive_web_flux_example.reactive_web_flux_example.Entity;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.relational.core.mapping.Table;
import javax.persistence.*;
@Table(value = "subscription")
@Data
public class Subscription {
      @Id
      @GeneratedValue(strategy = GenerationType.IDENTITY)
      private long subscriptionId;
      private String subscriptionName;
      @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
      @JoinColumn(name = "customer_id", nullable = false)
      @JsonIgnoreProperties("customer")
      private Customer customer;
 }

I am also pasting my error logs which intellij has generated

 2021-12-31 13:37:10.358  INFO 18713 --- [           main]                r.r.ReactiveWebFluxExampleApplication    : No active profile set, falling back to default      profiles: default
 2021-12-31 13:37:11.131  INFO 18713 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data R2DBC repositories in DEFAULT mode.
 2021-12-31 13:37:11.278  INFO 18713 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 141 ms.   Found 2 R2DBC repository interfaces.
 2021-12-31 13:37:12.696  INFO 18713 --- [           main] o.s.b.web.embedded.netty.NettyWebServer  : Netty started on port 8080
 2021-12-31 13:37:12.709  INFO 18713 --- [           main] r.r.ReactiveWebFluxExampleApplication    : Started ReactiveWebFluxExampleApplication in 2.858 seconds (JVM running for 3.349)
  2021-12-31 13:37:20.071 ERROR 18713 --- [or-http-epoll-3] a.w.r.e.AbstractErrorWebExceptionHandler : [e12abe35-1]  500 Server Error for HTTP POST "/customer/save"

java.lang.IllegalArgumentException: Unsupported array type: reactive_web_flux_example.reactive_web_flux_example.Entity.Subscription
at    org.springframework.data.r2dbc.dialect.PostgresDialect$R2dbcArrayColumns.getArrayType(PostgresDialect.java:164) ~[spring-data-r2dbc-1.4.0.jar:1.4.0]
  Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException: 
  Error has been observed at the following site(s):
*__checkpoint ⇢ Handler  reactive_web_flux_example.reactive_web_flux_example.Controller.customerController#addCustomer(CustomerRequestModel) [DispatcherHandler]
*__checkpoint ⇢ HTTP POST "/customer/save" [ExceptionHandlingWebHandler]
  Original Stack Trace:
    at   org.springframework.data.r2dbc.dialect.PostgresDialect$R2dbcArrayColumns.getArrayType(PostgresDialect.java:164) ~[spring-data-r2dbc-1.4.0.jar:1.4.0]
    at  org.springframework.data.r2dbc.convert.MappingR2dbcConverter.getArrayValue(MappingR2dbcConverter.java:548) ~[spring-data-r2dbc-1.4.0.jar:1.4.0]
    at  org.springframework.data.r2dbc.core.DefaultReactiveDataAccessStrategy.getArrayValue(DefaultReacti veDataAccessStrategy.java:269) ~[spring-data-r2dbc-1.4.0.jar:1.4.0]
    at  org.springframework.data.r2dbc.core.DefaultReactiveDataAccessStrategy.getOutboundRow(DefaultReact iveDataAccessStrategy.java:209) ~[spring-data-r2dbc-1.4.0.jar:1.4.0]
    at  org.springframework.data.r2dbc.core.R2dbcEntityTemplate.lambda$doInsert$7(R2dbcEntityTemplate.jav a:577) ~[spring-data-r2dbc-1.4.0.jar:1.4.0]
    at reactor.core.publisher.FluxFlatMap.trySubscribeScalarMap(FluxFlatMap.java:152)  ~[reactor-core-3.4.13.jar:3.4.13]
    at reactor.core.publisher.MonoFlatMap.subscribeOrReturn(MonoFlatMap.java:53) ~[reactor- core-3.4.13.jar:3.4.13]
    at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:57)  ~[reactor-core-3.4.13.jar:3.4.13]
    at reactor.core.publisher.MonoUsingWhen.subscribe(MonoUsingWhen.java:87) ~[reactor-  core-3.4.13.jar:3.4.13]
    at reactor.core.publisher.Mono.subscribe(Mono.java:4400) ~[reactor- core-3.4.13.jar:3.4.13]
    at reactor.core.publisher.FluxFlatMap.trySubscribeScalarMap(FluxFlatMap.java:200)  ~[reactor-core-3.4.13.jar:3.4.13]
    at reactor.core.publisher.MonoFlatMap.subscribeOrReturn(MonoFlatMap.java:53) ~[reactor- core-3.4.13.jar:3.4.13]
    at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:57)  ~[reactor-core-3.4.13.jar:3.4.13]
    at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:157) ~[reactor- core-3.4.13.jar:3.4.13]
    at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1816)  ~[reactor-core-3.4.13.jar:3.4.13]
    at reactor.core.publisher.MonoFlatMap$FlatMapInner.onNext(MonoFlatMap.java:249)  ~[reactor-core-3.4.13.jar:3.4.13]
    at  reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onNext(FluxOnErrorResume.java:79)  ~[reactor-core-3.4.13.jar:3.4.13]
    at reactor.core.publisher.FluxPeek$PeekSubscriber.onNext(FluxPeek.java:200) ~[reactor- core-3.4.13.jar:3.4.13]
    at reactor.core.publisher.FluxPeek$PeekSubscriber.onNext(FluxPeek.java:200) ~[reactor-  core-3.4.13.jar:3.4.13]
    at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.complete(MonoIgnoreThen.java:284) ~       [reactor-core-3.4.13.jar:3.4.13]
    at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.onNext(MonoIgnoreThen.java:187)  ~       [reactor-core-3.4.13.jar:3.4.13]
    at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1816) ~        [reactor-core-3.4.13.jar:3.4.13]
    at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:151) ~[reactor-   core-3.4.13.jar:3.4.13]
    at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1816) ~    [reactor-core-3.4.13.jar:3.4.13]
    at reactor.core.publisher.MonoZip$ZipCoordinator.signal(MonoZip.java:251) ~[reactor-  core-3.4.13.jar:3.4.13]
    at reactor.core.publisher.MonoZip$ZipInner.onNext(MonoZip.java:336) ~[reactor-  core-3.4.13.jar:3.4.13]
    at   reactor.core.publisher.MonoPeekTerminal$MonoTerminalPeekSubscriber.onNext(MonoPeekTerminal.java:1  80) ~[reactor-core-3.4.13.jar:3.4.13]
    at   reactor.core.publisher.FluxDefaultIfEmpty$DefaultIfEmptySubscriber.onNext(FluxDefaultIfEmpty.java   :101) ~[reactor-core-3.4.13.jar:3.4.13]
    at    reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onNext(FluxSwitchIfEmpty.java:74) ~[reactor-core-3.4.13.jar:3.4.13]
    at    reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onNext(FluxOnErrorResume.java:79) ~[reactor-core-3.4.13.jar:3.4.13]
     at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1816) ~   [reactor-core-3.4.13.jar:3.4.13]
    at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:151) ~[reactor-  core-3.4.13.jar:3.4.13]
    at   reactor.core.publisher.FluxContextWrite$ContextWriteSubscriber.onNext(FluxContextWrite.java:107)    ~       [reactor-core-3.4.13.jar:3.4.13]
    at reactor.core.publisher.FluxMapFuseable$MapFuseableConditionalSubscriber.onNext(FluxMapFuseable.java:295) ~[reactor-core-3.4.13.jar:3.4.13]
    at reactor.core.publisher.FluxFilterFuseable$FilterFuseableConditionalSubscriber.onNext(FluxFilterFuseable.java:337) ~[reactor-core-3.4.13.jar:3.4.13]
    at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1816) ~[reactor-core-3.4.13.jar:3.4.13]
    at reactor.core.publisher.MonoCollect$CollectSubscriber.onComplete(MonoCollect.java:159) ~[reactor-core-3.4.13.jar:3.4.13]
    at reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:142) ~[reactor-core-3.4.13.jar:3.4.13]
    at reactor.core.publisher.FluxPeek$PeekSubscriber.onComplete(FluxPeek.java:260) ~[reactor-core-3.4.13.jar:3.4.13]
    at reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:142) ~[reactor-core-3.4.13.jar:3.4.13]
    at reactor.netty.channel.FluxReceive.onInboundComplete(FluxReceive.java:400) ~[reactor-netty-core-1.0.14.jar:1.0.14]
    at reactor.netty.channel.ChannelOperations.onInboundComplete(ChannelOperations.java:419) ~[reactor-netty-core-1.0.14.jar:1.0.14]
    at reactor.netty.http.server.HttpServerOperations.onInboundNext(HttpServerOperations.java:590) ~[reactor-netty-http-1.0.14.jar:1.0.14]
    at reactor.netty.channel.ChannelOperationsHandler.channelRead(ChannelOperationsHandler.java:93) ~[reactor-netty-core-1.0.14.jar:1.0.14]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.72.Final.jar:4.1.72.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[netty-transport-4.1.72.Final.jar:4.1.72.Final]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) ~[netty-transport-4.1.72.Final.jar:4.1.72.Final]
    at reactor.netty.http.server.HttpTrafficHandler.channelRead(HttpTrafficHandler.java:264) ~[reactor-netty-http-1.0.14.jar:1.0.14]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.72.Final.jar:4.1.72.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[netty-transport-4.1.72.Final.jar:4.1.72.Final]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) ~[netty-transport-4.1.72.Final.jar:4.1.72.Final]
    at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:436) ~[netty-transport-4.1.72.Final.jar:4.1.72.Final]
    at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:324) ~[netty-codec-4.1.72.Final.jar:4.1.72.Final]
    at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:296) ~[netty-codec-4.1.72.Final.jar:4.1.72.Final]
    at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:251) ~[netty-transport-4.1.72.Final.jar:4.1.72.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.72.Final.jar:4.1.72.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[netty-transport-4.1.72.Final.jar:4.1.72.Final]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) ~[netty-transport-4.1.72.Final.jar:4.1.72.Final]
    at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410) ~[netty-transport-4.1.72.Final.jar:4.1.72.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.72.Final.jar:4.1.72.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[netty-transport-4.1.72.Final.jar:4.1.72.Final]
    at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919) ~[netty-transport-4.1.72.Final.jar:4.1.72.Final]
    at io.netty.channel.epoll.AbstractEpollStreamChannel$EpollStreamUnsafe.epollInReady(AbstractEpollStreamChannel.java:795) ~[netty-transport-classes-epoll-4.1.72.Final.jar:4.1.72.Final]
    at io.netty.channel.epoll.EpollEventLoop.processReady(EpollEventLoop.java:480) ~[netty-transport-classes-epoll-4.1.72.Final.jar:4.1.72.Final]
    at io.netty.channel.epoll.EpollEventLoop.run(EpollEventLoop.java:378) ~[netty-transport-classes-epoll-4.1.72.Final.jar:4.1.72.Final]
    at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:986) ~[netty-common-4.1.72.Final.jar:4.1.72.Final]
    at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.72.Final.jar:4.1.72.Final]
    at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ~[netty-common-4.1.72.Final.jar:4.1.72.Final]
    at java.base/java.lang.Thread.run(Thread.java:829) ~[na:na]

I referred internet to resolve this problem, but didn't come across to anything helpful. Any help would be appreciable.

  • `@OneToMany` is hibernate. Standard Hibernate does not have support for R2DBC based connections. You need to specifically use http://hibernate.org/reactive/ – Toerktumlare Dec 31 '21 at 10:06
  • As @Toerktumlare said, you are using JPA annotations (OneToMany, GeneratedValue, ManyToOne, JoinColumn) which are not supported by Spring Data R2DBC. Hibernate reactive only supports Vert.x but not Spring Data. You can use [lc-spring-data-r2dbc](https://github.com/lecousin/lc-spring-data-r2dbc) to support links between tables in a similar way as JPA, or implement the joins by yourself, but natively Spring Data does not support relationships with R2DBC – Zinc Jan 02 '22 at 09:23

1 Answers1

0

You can choose to delete all the records associated to the customer by running the command below on your DB. On your query console the command below. NOTE: If this works if you intend to delete all records associated to that customer.

alter table subscriptions
    add constraint subscriptions_subscription_id_fk
        foreign key (customer_id) references customers (id) on delete  cascade;

This is equivalent to

    @ManyToOne(mappedBy = "customer", cascade = CascadeType.ALL)

When using JPA

Davies Tonui
  • 33
  • 1
  • 2
  • 9