Open yrodiere opened 2 years ago
On a first glance, this basic sample works fine with multiple entities.
Is this SpannerServiceContributor.java
specifically used with quarkus?
@olavloite do you have any context on this by any chance?
On a first glance, this basic sample works fine with multiple entities. Is this
SpannerServiceContributor.java
specifically used with quarkus?
This sample is not relevant, because the problem is not about having multiple entities.
The problem is about having multiple persistence units, i.e. multiple instances of Hibernate ORM in the same application. In that case, you have multiple service registries and multiple entity manager factories. If your SpannerSchemaManagementTool
is a singleton, it will get injected (through this method) multiple times with the service registries from each persistence unit, and only the last injection will win. You will end up with multiple persistence units using a single SpannerSchemaManagementTool
that internally relies on metadata from the last persistence unit. This cannot work.
If you need a reproducer beyond the one from https://github.com/quarkusio/quarkus/issues/24742, you only need to set up an application with two persistence units, each with different entities, and each pointing to a different Google Spanner instance, with database schema generation enabled in Hibernate ORM (that should be the default). ~You'll see that SpannerSchemaManagementTool
will create the same tables in both Google Spanner instances.~ Actually, the problem is rather that it will create all tables in one Google Spanner instance, instead of some in the first instance and some in the second instance. Which is arguably even worse.
Is this
SpannerServiceContributor.java
specifically used with quarkus?
SpannerServiceContributor.java
comes from google-cloud-spanner-hibernate
, not from Quarkus. It is used as soon as google-cloud-spanner-hibernate
is in the classpath, as far as I can tell.
Thank you for the detailed explanation. We will look into this.
@yrodiere we welcome contributions for this from the community.
@meltsufin Then let's hope the community will provide a contribution. I'm not personally a Spanner user, so fixing bugs in this project unfortunately cannot be a priority for me, but I'll see if I have time to have a look in the future.
Thanks for providing the initial context for this issue! We will keep this issue open as we await contributions from the community.
See here:
https://github.com/GoogleCloudPlatform/google-cloud-spanner-hibernate/blob/2c97da01f00eaa0865c9205a8f8788fa896aee60/google-cloud-spanner-hibernate-dialect/src/main/java/com/google/cloud/spanner/hibernate/SpannerServiceContributor.java#L42-L45
SpannerSchemaManagementTool
is effectively a singleton, but it gets injected with information specific to the persistence unit. If it's reused across multiple persistence unit, it will only keep information about the last persistence unit to start, and schema management for the previous persistence units will not work correctly.You can find more information on the kind of problems this leads to here: https://github.com/quarkusio/quarkus/issues/24742
In order to solve this problem,
SpannerServiceContributor
should create one instance ofSpannerSchemaManagementTool
each time the service is initiated. That's whatorg.hibernate.tool.schema.internal.SchemaManagementToolInitiator
, the default implementation, does.