mysql Quarkus - Panache始终使用默认数据源,而不是分配的DataSource

njthzxwz  于 2023-11-16  发布在  Mysql
关注(0)|答案(1)|浏览(116)

我试图对两个不同的数据源(PostgreSQL和MySQL)进行CRUD,然而,似乎即使将@DataSource分配给repository类后,它仍然使用默认值。
这是我得到的错误:

2023-10-27 17:54:28,443 ERROR [io.qua.hib.orm.run.sch.SchemaManagementIntegrator] (Hibernate post-boot validation thread for <default>) Failed to validate Schema: Schema-validation: missing table [cash_postgres]

字符串
我假设Quarkus使用默认数据源是因为cash_postgres不存在于MySQL数据库中,而只存在于我的PostgreSQL中。
我试着遵循这个文档,和其他StackOverflow/Github问题/ticket,但仍然没有线索。
我的application.properties

quarkus.datasource.db-kind=mysql
quarkus.datasource.username=root
quarkus.datasource.jdbc.url=jdbc:mysql://localhost:3307/mysqldb

quarkus.datasource."mysqldatasource".db-kind=mysql
quarkus.datasource."mysqldatasource".username=root
quarkus.datasource."mysqldatasource".jdbc.url=jdbc:mysql://localhost:3307/mysqldb

quarkus.datasource."postgresqldatasource".db-kind=postgresql
quarkus.datasource."postgresqldatasource".username=user
quarkus.datasource."postgresqldatasource".password=password
quarkus.datasource."postgresqldatasource".jdbc.url=jdbc:postgresql://localhost:5431/postgresdb

quarkus.http.port=8080


这是我的实体:

@Entity
@Table(name = "cash_mysql")
public class CashMySQL {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private int id;

    @Column(name = "amount")
    private int amount;

    @Column(name = "create_time")
    private Date createTime;

    @Column(name = "update_time")
    private Date updateTime;

    @Column(name = "created_by")
    private String createdBy;

    @Column(name = "updated_by")
    private String updatedBy;
}

@Entity
@Table(name = "cash_postgres")
public class CashPostgres {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private int id;

    @Column(name = "amount")
    private int amount;

    @Column(name = "create_time")
    private Date createTime;

    @Column(name = "update_time")
    private Date updateTime;

    @Column(name = "created_by")
    private String createdBy;

    @Column(name = "updated_by")
    private String updatedBy;
}


这是我的回收

@ApplicationScoped
@DataSource("mysqldatasource")
public class CashMySQLRepository implements PanacheRepository<CashMySQL> {}

@ApplicationScoped
@DataSource("postgresqldatasource")
public class CashPostgresRepository implements PanacheRepository<CashPostgres> {}


这是我的资源

@Path("/benchmark")
public class MyResource {

    @Inject
    @DataSource("mysqldatasource")
    CashMySQLRepository cashMySQLRepository;
    @Inject
    @DataSource("postgresqldatasource")
    CashPostgresRepository cashPostgresRepository;
}


我真的很感激任何帮助

hpxqektj

hpxqektj1#

我们需要做的是

  • 创建两个持久性单元,一个用于mySql,一个用于Postgres,
  • 将两个Entity类移到单独的包中,
  • 将mySql持久性单元绑定到mySql数据源
  • 使用mySql Entity将包绑定到mySql持久性单元
  • 将postgres持久性单元绑定到mySql数据源
  • 使用mySql Entity将包绑定到postgres持久化单元。

当我们假设类CashMySQL位于包de.turing85.persistence.entity.mysql中,类CashPostgres位于包de.turing85.persistence.entity.postgres中时,application.properties可能看起来像这样:

quarkus.datasource."mysqldatasource".db-kind=mysql
quarkus.datasource."postgresqldatasource".db-kind=postgresql

quarkus.hibernate-orm."mysql".database.generation=drop-and-create
quarkus.hibernate-orm."mysql".datasource=mysqldatasource
quarkus.hibernate-orm."mysql".packages=de.turing85.persistence.entity.mysql

quarkus.hibernate-orm."postgres".database.generation=drop-and-create
quarkus.hibernate-orm."postgres".datasource=postgresqldatasource
quarkus.hibernate-orm."postgres".packages=de.turing85.persistence.entity.postgres

字符串
我们的端点有一个相应的实现:

@Path("cash")
@Produces(MediaType.APPLICATION_JSON)
public class CashEndpoint {
  private static final Random RANDOM = new Random();

  private final CashMySQLRepository mySqlRepository;
  private final CashPostgresRepository postgresRepository;

  public CashEndpoint(@DataSource("mysqldatasource") CashMySQLRepository mySqlRepository,
      @DataSource("postgresqldatasource") CashPostgresRepository postgresRepository) {
    this.mySqlRepository = mySqlRepository;
    this.postgresRepository = postgresRepository;
  }

  @POST
  @Transactional
  public int[] generateRandomEntry() {
    Date now = new Date();
    int amount = RANDOM.nextInt(1000);
    String createdBy = "foo" + RANDOM.nextInt();
    String updatedBy = "bar" + RANDOM.nextInt();
    // @formatter:off
    CashMySQL cashMySQL = CashMySQL.builder()
        .amount(amount)
        .createdBy(createdBy)
        .updatedBy(updatedBy)
        .createTime(now)
        .updateTime(now)
        .build();
    // @formatter:on
    mySqlRepository.persist(cashMySQL);

    // @formatter:off
    CashPostgres cashPostgres = CashPostgres.builder()
        .amount(amount)
        .createdBy(createdBy)
        .updatedBy(updatedBy)
        .createTime(now)
        .updateTime(now)
        .build();
    // @formatter:on
    postgresRepository.persist(cashPostgres);
    return new int[] {cashMySQL.getId(), cashPostgres.getId()};
  }

  @GET
  @Path("mysql/{id}")
  public CashMySQL getFromMySqlById(@PathParam("id") long id) {
    return mySqlRepository.findById(id);
  }

  @GET
  @Path("postgres/{id}")
  public CashPostgres getFromPostgresById(@PathParam("id") long id) {
    return postgresRepository.findById(id);
  }
}


幸福路径测试:

@QuarkusTest
@TestHTTPEndpoint(CashEndpoint.class)
class CashEndpointTest {

  @Inject
  @DataSource("mysqldatasource")
  CashMySQLRepository mySqlRepository;

  @Inject
  @DataSource("postgresqldatasource")
  CashPostgresRepository postgresRepository;

  @Test
  void testPostAndGet() {
    // @formatter:off
    long[] ids = RestAssured
        .when().post()
        .then()
            .statusCode(Response.Status.OK.getStatusCode())
            .extract().body().as(long[].class);

    CashMySQL cashMySqlFromHttp = RestAssured
        .when().get("/mysql/%d".formatted(ids[0]))
        .then()
            .statusCode(Response.Status.OK.getStatusCode())
            .extract().body().as(CashMySQL.class);
    // @formatter:on
    CashMySQL cashMySqlFromDb = mySqlRepository.findById(ids[0]);
    assertThat(cashMySqlFromHttp).isEqualTo(cashMySqlFromDb);

    // @formatter:off
    CashPostgres cashPostgresFromHttp = RestAssured
        .when().get("/postgres/%d".formatted(ids[0]))
        .then()
            .statusCode(Response.Status.OK.getStatusCode())
            .extract().body().as(CashPostgres.class);
    // @formatter:on
    CashPostgres cashPostgresFromDb = postgresRepository.findById(ids[0]);
    assertThat(cashPostgresFromHttp).isEqualTo(cashPostgresFromDb);
  }
}


我们可以验证行为。
完整的例子可以在this github.com repository中找到。

相关问题