blaze-persistence icon indicating copy to clipboard operation
blaze-persistence copied to clipboard

Add support for composite user types in Hibernate

Open AFbenHassine opened this issue 6 years ago • 6 comments

Currently it is not possible to query composite properties of an entity. However, Hibernate does support such constructions through the CompositeUserType interface and @Type annotation. In our implementation of Java Money using Jadira we encountered such a composite type; Money, which consists of the properties amount and currency. We would like to be able to query it correctly using Blaze.

Currently, attempting to query a composite type throws

java.lang.IllegalArgumentException: The join path [product.price.amount] has a non joinable part [price.amount]

AFbenHassine avatar Mar 20 '19 10:03 AFbenHassine

I recently started working on this issue (https://github.com/jwgmeligmeyling/blaze-persistence/commit/6c2ca771c34c5c3f43cb903921d8f861906a1f03). Basically we need to treat Composite types as embeddables. Making this change in our metamodel is relatively easy. However, a lot of code still uses the plain JPA metamodel. In order to support composite user types fully, we need to change these occurrences of JPA metamodel access to that they use BP's internal metamodel instead. This is a change we're willing to make, because it's not only required for dereferencing composite user types but its also relevant for dereferencing JSON properties.

jwgmeligmeyling avatar May 08 '20 23:05 jwgmeligmeyling

Since Hibernate 5.4.22 Composite User Types are expressed in the JPA Metamodel as Embeddables. As a result, accessing composite user type properties works in Blaze-Persistence when using Hibernate 5.4.22.

Adding support for it in Blaze-Persistence would make it possible to dereference composite user type properties with Hibernate versions prior to 5.4.22 as well.

For now the workaround around this issue is simply upgrading to the latest Hibernate version.

That said, there are still various other enhancements that would benefit from a custom JPA metamodel wrapper in Blaze-Persistence.

jwgmeligmeyling avatar Oct 14 '20 10:10 jwgmeligmeyling

Update where this currently is:

(June 20th, 2020)

So if the ExtendedManagedType were to be removed to parser, then transitively that affects AttributeAccessor, AttributePath, ExtendedAttribute , JoinTable, JoinType , JpaMetamodelAccessor and JpaProvider. Which are mostly SPI classes, except for JoinType for which we could also consider to duplicate instead. This is where I am at now : https://github.com/Blazebit/blaze-persistence/compare/master...jwgmeligmeyling:Hibernate-CompositeUserType I think the diff is a good example of where this is going, it does implement the following things:

  • Move a couple of classes from SPI to parser, so the ExtendedMetamodel becomes usable in Parser
  • The changes to the API/test suite to make the above compile
  • Initialize a custom JPA metamodel for composite basic types in the extended metamodel
  • Grab the extended metamodel for the composite basic type in the PathTargetResolvingExpressionVisitor , that fixes two of the tests Above two ways can obviously be extended throughout other portions of the code that use the JPA metamodel to fix other usecases (like the third test, which involves CTE's)

(Aug 30th, 2021)

The primary issue is that not just core uses the metamodel, but parser as well. which means that we have to move a few things from spi to parser to pull this off I wasn't liking that Also we need to change the delegate methods to a full wrapper. So that chained methods also return objects from the extended metamodel. In the end I couldn't see how the change could be made without breaking SPI/API changes

jwgmeligmeyling avatar Oct 12 '21 21:10 jwgmeligmeyling

What do you think about merging the parser into core-impl? I don't think there is a real need to have the parser separately anyway. Merging would make all of this a lot easier I guess? The parser is not something that we particularly mention as API so I would say it is fine to do the move for a minor release i.e. for 1.7

beikov avatar Oct 13 '21 06:10 beikov

That's certainly possible. Didn't really consider it an option as parser was recently separated from core as far as I remember 😄

jwgmeligmeyling avatar Oct 13 '21 08:10 jwgmeligmeyling

It is actually a separate project since the beginning. The only reason for needing it as separate project is for modules like entity-view-impl etc. which do parsing at boot time, but I think it should be fine to instead depend on core-impl. I don't expect a different implementation of Blaze-Persistence anyway 😆

beikov avatar Oct 13 '21 08:10 beikov