簡體   English   中英

Quarkus測試失敗,因為未找到本機DayOfWeek

[英]Quarkus Test fails in native becaus DayOfWeek not found

我創建了一個簡單的quarkus(0.21.2版)應用程序,該應用程序將休眠orm與panache一起使用將實體保存到h2數據庫。 該實體包括DaysOfWeekElementCollection 我還創建了一些測試來確保CURD能夠正常工作。 這些測試都可以正常運行,但是當我天真地運行它們時,出現以下異常:

Exception in thread "main" java.lang.RuntimeException: Failed to start quarkus
    at io.quarkus.runner.ApplicationImpl1.doStart(ApplicationImpl1.zig:126)
    at io.quarkus.runtime.Application.start(Application.java:91)
    at io.quarkus.runtime.Application.run(Application.java:204)
    at io.quarkus.runner.GeneratedMain.main(GeneratedMain.zig:34)
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory
    at io.quarkus.hibernate.orm.runtime.boot.FastBootEntityManagerFactoryBuilder.persistenceException(FastBootEntityManagerFactoryBuilder.java:113)
    at io.quarkus.hibernate.orm.runtime.boot.FastBootEntityManagerFactoryBuilder.build(FastBootEntityManagerFactoryBuilder.java:67)
    at io.quarkus.hibernate.orm.runtime.FastBootHibernatePersistenceProvider.createEntityManagerFactory(FastBootHibernatePersistenceProvider.java:54)
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:79)
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:54)
    at io.quarkus.hibernate.orm.runtime.JPAConfig$LazyPersistenceUnit.get(JPAConfig.java:109)
    at io.quarkus.hibernate.orm.runtime.JPAConfig.startAll(JPAConfig.java:57)
    at io.quarkus.hibernate.orm.runtime.HibernateOrmRecorder.startAllPersistenceUnits(HibernateOrmRecorder.java:77)
    at io.quarkus.deployment.steps.HibernateOrmProcessor$startPersistenceUnits19.deploy_0(HibernateOrmProcessor$startPersistenceUnits19.zig:51)
    at io.quarkus.deployment.steps.HibernateOrmProcessor$startPersistenceUnits19.deploy(HibernateOrmProcessor$startPersistenceUnits19.zig:70)
    at io.quarkus.runner.ApplicationImpl1.doStart(ApplicationImpl1.zig:90)
    ... 3 more
Caused by: org.hibernate.MappingException: Could not create DynamicParameterizedType for type: org.hibernate.type.EnumType
    at org.hibernate.mapping.SimpleValue.createParameterImpl(SimpleValue.java:768)
    at org.hibernate.mapping.SimpleValue.getType(SimpleValue.java:470)
    at org.hibernate.mapping.SimpleValue.isValid(SimpleValue.java:455)
    at org.hibernate.mapping.Collection.validate(Collection.java:315)
    at org.hibernate.boot.internal.MetadataImpl.validate(MetadataImpl.java:347)
    at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:461)
    at io.quarkus.hibernate.orm.runtime.boot.FastBootEntityManagerFactoryBuilder.build(FastBootEntityManagerFactoryBuilder.java:65)
    ... 12 more
Caused by: org.hibernate.boot.registry.classloading.spi.ClassLoadingException: Unable to load class [java.time.DayOfWeek]
    at io.quarkus.hibernate.orm.runtime.service.FlatClassLoaderService.classForName(FlatClassLoaderService.java:39)
    at org.hibernate.mapping.SimpleValue.createParameterImpl(SimpleValue.java:755)
    ... 18 more
Caused by: java.lang.ClassNotFoundException: java.time.DayOfWeek
    at com.oracle.svm.core.hub.ClassForNameSupport.forName(ClassForNameSupport.java:60)
    at java.lang.Class.forName(DynamicHub.java:1174)
    at io.quarkus.hibernate.orm.runtime.service.FlatClassLoaderService.classForName(FlatClassLoaderService.java:37)
    ... 19 more

我的實體看起來像這樣:

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.quarkus.hibernate.orm.panache.PanacheEntityBase;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.GenericGenerator;

import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.validation.constraints.NotNull;
import java.time.DayOfWeek;
import java.time.LocalTime;
import java.util.*;

import static org.hibernate.annotations.CascadeType.ALL;

@Entity
@JsonIgnoreProperties(ignoreUnknown = true)
public class OpeningTimes extends PanacheEntityBase {
  @Id
  @GeneratedValue(generator = "UUID")
  @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator")
  private UUID id;

  @NotNull
  private String name;
  private String description;
  private LocalTime timeFrom;
  private LocalTime timeTo;

  @ElementCollection
  @Cascade(value = {ALL})
  private Collection<DayOfWeek> daysOfWeek;

  /**
   * DO NOT USE! ONLY FOR JPA!
   */
  OpeningTimes() {
    super();
    name = "";
  }

  @JsonCreator
  public OpeningTimes(
      @JsonProperty("name") String name,
      @JsonProperty("timeFrom") LocalTime timeFrom,
      @JsonProperty("timeTo") LocalTime timeTo,
      @JsonProperty("daysOfWeek") Collection<DayOfWeek> daysOfWeek) {
    this.name = name;
    this.timeFrom = timeFrom;
    this.timeTo = timeTo;
    this.daysOfWeek = new HashSet<>(daysOfWeek);
  }

  public OpeningTimes(String name, LocalTime from, LocalTime to, DayOfWeek... daysOfWeek) {
    this(name, from, to, new ArrayList<>(Arrays.asList(daysOfWeek)));
  }

  public LocalTime getTimeFrom() {
    return timeFrom;
  }

  public void setTimeFrom(LocalTime timeFrom) {
    this.timeFrom = timeFrom;
  }

  public LocalTime getTimeTo() {
    return timeTo;
  }

  public void setTimeTo(LocalTime timeTo) {
    this.timeTo = timeTo;
  }

  public Collection<DayOfWeek> getDaysOfWeek() {
    return daysOfWeek;
  }

  public void setDaysOfWeek(Set<DayOfWeek> daysOfWeek) {
    this.daysOfWeek = daysOfWeek;
  }

  public UUID getId() {
    return id;
  }

  public void setId(UUID id) {
    this.id = id;
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public String getDescription() {
    return description;
  }

  public void setDescription(String description) {
    this.description = description;
  }

  @Override
  public boolean equals(Object o) {
    if (this == o) return true;
    if (!(o instanceof OpeningTimes)) return false;
    OpeningTimes that = (OpeningTimes) o;
    return Objects.equals(getId(), that.getId())
            && Objects.equals(getName(), that.getName())
            && Objects.equals(getDescription(), that.getDescription())
            && Objects.equals(getTimeFrom(), that.getTimeFrom())
            && Objects.equals(getTimeTo(), that.getTimeTo())
            && Objects.equals(getDaysOfWeek(), that.getDaysOfWeek());
  }

  @Override
  public int hashCode() {
    return Objects.hash(
            getId(), getName(), getDescription(), getTimeFrom(), getTimeTo(), getDaysOfWeek());
  }

  @Override
  public String toString() {
    return "OpeningTimes{"
            + "id="
            + id
            + ", name='"
            + name
            + '\''
            + ", description='"
            + description
            + '\''
            + ", timeFrom="
            + timeFrom
            + ", timeTo="
            + timeTo
            + ", daysOfWeek="
            + daysOfWeek
            + '}';
  }

  public void merge(OpeningTimes openingTimes) {
    this.name = openingTimes.name;
    this.description = openingTimes.description;
    this.timeFrom = openingTimes.timeFrom;
    this.timeTo = openingTimes.timeTo;
    this.daysOfWeek = openingTimes.daysOfWeek;
  }
}

這是我的測試:

import io.quarkus.hibernate.orm.panache.PanacheEntityBase;
import io.quarkus.test.common.QuarkusTestResource;
import io.quarkus.test.h2.H2DatabaseTestResource;
import io.quarkus.test.junit.QuarkusTest;
import io.restassured.http.ContentType;
import io.restassured.mapper.ObjectMapperType;
import io.restassured.mapper.TypeRef;
import io.restassured.response.Response;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.transaction.Transactional;
import java.time.DayOfWeek;
import java.time.LocalTime;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

import static io.restassured.RestAssured.given;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;

@QuarkusTest
@QuarkusTestResource(H2DatabaseTestResource.class)
class OpeningsResourceTest {
  private static final Logger LOG = LoggerFactory.getLogger(OpeningsResourceTest.class);

  @Test
  void testSaveOpening() {
    OpeningTimes opening =
        new OpeningTimes(
            "Test opening", LocalTime.MIN, LocalTime.NOON, DayOfWeek.MONDAY, DayOfWeek.THURSDAY);
    Response response =
        given()
            .when()
            .contentType(ContentType.JSON)
            .body(opening, ObjectMapperType.JACKSON_2)
            .post("/service/events/openings");
    LOG.debug(response.andReturn().body().prettyPrint());
    OpeningTimes responseObject = response.then().statusCode(200).extract().as(OpeningTimes.class);

    // Set the id because its generated on saving
    opening.setId(responseObject.getId());
    assertThat(responseObject, equalTo(opening));
  }

  @Test
  void testGetOpening() {
    OpeningTimes testdata = saveTestdata().get(0);
    Response response = given().when().get("/service/events/openings/{id}/", testdata.getId());
    OpeningTimes responseObject = response.then().statusCode(200).extract().as(OpeningTimes.class);
    assertThat(responseObject, equalTo(testdata));
  }

  @Test
  void testDeleteOpening() {
    OpeningTimes testdata = saveTestdata().get(0);
    // Delete
    given()
            .when()
            .delete("/service/events/openings/{id}/", testdata.getId())
            .then()
            .statusCode(204);
    // Check if it is deleted
    given().when().get("/service/events/openings/{id}/", testdata.getId()).then().statusCode(204);
  }

  @Test
  void testChangeOpening() {
    OpeningTimes testdata = saveTestdata().get(0);
    testdata.setDescription("Example description");
    Response response =
            given()
                    .when()
                    .contentType(ContentType.JSON)
                    .body(testdata, ObjectMapperType.JACKSON_2)
                    .put("/service/events/openings/");
    LOG.debug(response.andReturn().body().prettyPrint());
    response.then().statusCode(200).extract().as(OpeningTimes.class);

    OpeningTimes changedOpening =
            given()
                    .when()
                    .get("/service/events/openings/{id}", testdata.getId())
                    .then()
                    .statusCode(200)
                    .extract()
                    .as(OpeningTimes.class);
    assertThat(changedOpening, is(testdata));
  }

  private List<OpeningTimes> saveTestdata() {
    OpeningTimes opening1 =
        new OpeningTimes(
            "Test opening", LocalTime.MIN, LocalTime.NOON, DayOfWeek.MONDAY, DayOfWeek.THURSDAY);
    OpeningTimes opening2 =
        new OpeningTimes("Test opening 2", LocalTime.MIN, LocalTime.NOON, DayOfWeek.FRIDAY);
    opening1 =
            given()
                    .contentType(ContentType.JSON)
                    .body(opening1, ObjectMapperType.JACKSON_2)
                    .post("/service/events/openings")
                    .then()
                    .extract()
                    .as(OpeningTimes.class);
    opening2 =
            given()
                    .contentType(ContentType.JSON)
                    .body(opening2, ObjectMapperType.JACKSON_2)
                    .post("/service/events/openings")
                    .then()
                    .extract()
                    .as(OpeningTimes.class);
    return Arrays.asList(opening1, opening2);
  }

  @Test
  void testGetAll() {
    List<OpeningTimes> testdata = saveTestdata();
    Collection<OpeningTimes> openings =
        given()
            .when()
            .get("/service/events/openings")
            .then()
            .statusCode(200)
            .extract()
            .as(new TypeRef<Collection<OpeningTimes>>() {});

    assertThat(openings, is(testdata));
  }

  @AfterEach
  @Transactional
  void cleanUpDatabase() {
    // Delete all won't work because of the element collection
    OpeningTimes.findAll().stream().forEach(PanacheEntityBase::delete);
  }
}

和本機測試:

import io.quarkus.test.junit.SubstrateTest;

@SubstrateTest
public class NativeOpeningsResourceIT extends OpeningsResourceTest {
    // Execute the same tests but in native mode.
}

我不知道為什么它找不到java.time.DayOfWeek

似乎本機圖像工具沒有在本機圖像中包含java.time.DayOfWeek類。 SubstratVM在封閉環境中工作,只能訪問在本機映像編譯期間發現的類或專門注冊用於反射的類。

您可以按照本部分的說明注冊java.time.DayOfWeek類: https : java.time.DayOfWeek

您可以在Entity類上嘗試使用注釋,但是我認為您需要將java.time.DayOfWeek類包含在reflection-config.json文件中,因為我不確定注釋是否會包含您的Entity使用的所有類。或僅您的Entity類。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM