Quarkus Reactive с Vert.x и Hibernate Reactive / java.lang.NullPointerException: невозможно сохранить в массиве объектов, поскольку this.loadedState имеет значение null

Я пытаюсь использовать quarkus reactive с vert.x и hibernate reactive.

это мой pom.xml:

<quarkus-plugin.version>1.12.2.Final</quarkus-plugin.version>

а также

<quarkus.platform.version>1.12.2.Final</quarkus.platform.version>

с участием:

        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-resteasy-reactive</artifactId>
        </dependency>

        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-resteasy-reactive-jackson</artifactId>
        </dependency>

        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-reactive-mysql-client</artifactId>
        </dependency>

        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-vertx-web</artifactId>
        </dependency>

        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-hibernate-reactive</artifactId>
        </dependency>

        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-reactive-pg-client</artifactId>
        </dependency>

это мой файл application.properties:

# postgres-configuration
quarkus.datasource.db-kind=postgresql
quarkus.datasource.username=partner_usr
quarkus.datasource.password=postgrespw
quarkus.datasource.reactive.url=vertx-reactive:postgres://localhost:3310/partnerdb

# test, but not working (schema's won't created)
quarkus.hibernate-orm.database.generation.create-schemas=true

# working (drop-and-create only on mysql, not on postgres)
quarkus.hibernate-orm.database.generation=drop-and-create
quarkus.hibernate-orm.log.sql=true
quarkus.http.cors=true

Тогда у меня есть следующие объекты:

@Data
@MappedSuperclass
public abstract class IdEntity {

    @Id
    @SequenceGenerator(name = "entitySeq", sequenceName = "entitiy_id", allocationSize = 1, initialValue = 5)
    @GeneratedValue(generator = "entitySeq", strategy = GenerationType.AUTO)
    private Long id;
}
@Data
@Entity
@EqualsAndHashCode(callSuper = true)
public class Person extends IdEntity {

    private String firstName;
    private String lastName;

    public Person() {

    }

    @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private Address personAddress;

}
@Data
@Entity
@EqualsAndHashCode(callSuper = true)
public class Address extends IdEntity {

    private String street;
    private String houseNumber;
    private int postalCode;
    private String city;

    @OneToMany(orphanRemoval = true, mappedBy = "personAddress", fetch = FetchType.LAZY)
    private List<Person> persons = new ArrayList<>();

    public Address() {

    }
}

Теперь я вызываю реактивный веб-сервис с реактивным доступом к базе данных:

@Path("/person")
@ApplicationScoped
public class PersonResource {

    @Inject
    io.vertx.mutiny.pgclient.PgPool sqlClient;


    @Inject
    Mutiny.Session mutinySession;

    @GET
    //@Produces(MediaType.APPLICATION_JSON)
    @Path("/list-persons")
    @Route(path = "/list-persons", methods = HttpMethod.GET, produces = MediaType.APPLICATION_JSON)
    @Transactional
    public Multi<Person> listAllPersons() {

//        return sqlClient.query("SELECT * FROM Person ORDER BY lastName ASC").execute()
//            .onItem().transformToMulti(set -> Multi.createFrom().iterable(set))
//            .onItem().transform(this::transformPersons);

        return mutinySession.createQuery("SELECT f FROM Person f ORDER BY f.lastName")
            .getResults().onItem().transform(this::transformObject);


    }

    private Person transformObject(Object f) {
        return (Person)f;
    }

    private List<Object> transformPersons(Object f) {
        final Person person = (PartnerMockEntity)f;

        final List<Object> bogus = new ArrayList<>();
        bogus.add(partner);
        return bogus;
    }

}

Исключение:

Resulted in: com.fasterxml.jackson.databind.JsonMappingException: Cannot store to object array because "this.loadedState" is null (through reference chain: de.subito.model.Person["personAddress"]->de.subito.model.Address["person"])

Я пробовал использовать:

  • FetchType.EAGER по адресу лично
  • Я удалил связь @OneToMany в адресе: это решает ошибку (ура), но адреса не будут возвращены в результирующем json (идентификатор существует, но значения не извлекаются)

Вопрос в том, как я могу получить в реактивном режиме такие отношения, не получая ошибок? Или мне нужна угловая страница для правильного отображения?


person Tony B    schedule 19.03.2021    source источник


Ответы (1)


Как-то забыл о том, как работает fetchType.Lazy.

Просто добавьте запрос соединения в hql, и все будет работать, как ожидалось.

SELECT p from Person p left join fetch p.personAddress

При использовании этого запроса не возникает никакого сеанса / закрытого или любого другого исключения, и результат json будет отображаться, как ожидалось.

Дополнительное примечание: во избежание рекурсивной сериализации необходимо использовать

@JsonManagedReference and @JsonBackReference

Аннотации, в зависимости от ваших потребностей в ваших отношениях.

person Tony B    schedule 19.03.2021