[hibernate-dev] 6.0 - Type redesign

Steve Ebersole steve at hibernate.org
Fri Jul 22 09:32:40 EDT 2016


I get what you mean.  We have to start from a "bindable" root.  FWIW other
types beside entity could be a "contextualization root" depending on the
Metamodel method signature.

Obviously the return from Metamodel#embeddable(Class) could not.  But, we
could expose methods that would allow access the "embedded" form, e.g.:


   - Metamodel#embedded(ManagedType,String) - String is the embedded
   attribute role relative to ManagedType
   - Metamodel#embedded(Path)
   - Metamodel#embedded(AttributePath)
   - Metamodel#embedded(AttributeRole)
   - Metamodel#embedded(String)

etc

similar for collections.

I take "contextualization" to mean "providing a context back to a root".
And in that sense, yes, you grok and describe the exact point I am
struggling with now.  I could not communicate it clearly because I have
developed the proper terms and concepts to describe and model it.  So thank
you for the different perspective, it helps.  I am still going through your
larger reply and trying to distill it into my mental model.


On Fri, Jul 22, 2016 at 5:21 AM Emmanuel Bernard <emmanuel at hibernate.org>
wrote:

> The contextualization would only work when user calls metamodel.entity().
> Not the other methods
>
> > On 22 juil. 2016, at 11:14, Emmanuel Bernard <emmanuel at hibernate.org>
> wrote:
> >
> > The good news is that I am following you :D
> >
> > I think one of the option is some API to which you can pass the (JPA)
> > Type, a Path from root and it would return a structure qualifying the
> > embedded info and not just the embeddable.
> >
> > I'm making things up here
> >
> > //might not even need the type, could be guessed from the Path?
> > AttributeMapping am = mappingProvider.forPath(path);
> >
> > What's nasty is that it then requires two parallel APIs, or rather it
> > would not flow from an enhanced JPA type API.
> >
> > An alternative would be what I think you propose with the BindableType,
> > that is an extension point that describes the specifics of the
> > specialization when navigating from one node type to another. I think.
> >
> > An alternative that I can think of is as follows. I'm assuming that the
> > data that needs to be contextualized by the path is mapping in nature or
> > at least not at all represented in the JPA types.
> > Each (JPA) type instance would be inherently specific to the path it
> > comes from. It would keep exposing the JPA non contextualized info but
> > also add contextualized info.
> >
> > HibernateEntityType<Foo> fooModel =
> >  (HibernateEntityType<Foo>)
> entityManagerFactory.getMetamodel().entity(Foo.class); // considered a root
> for navigation
> >
> > for (HibernateSingularAttribute sa : fooModel.getSingularAttributes()) {
> >   if (sa.getPersistentAttributeType() == EMBEDDED) {
> >       HibernateEmbeddableType et = (HibernateEmbeddableType)
> sa.getType();
> >       for (HibernateSingularAttribute esa :
> fooModel.getSingularAttributes()) {
> >           if (esa.getPersistentAttributeType() == BASIC) {
> >               int span = esa.getPhysicalInfo().getColumnSpan();
> >           }
> >      }
> >    }
> > }
> >
> > Hopefully, JPA does not mandate == between different types.
> >
> > A question I have is how navigable and easy such API would be for a
> > persister. But that's something to explore.
> >
> > Emmanuel
> >
> >> On Thu 2016-07-21 21:10, Steve Ebersole wrote:
> >> Put another way, I think the problem (and probably the solution) here is
> >> similar to JPA's Bindable (and Path) concept.
> >>
> >>> On Thu, Jul 21, 2016 at 2:27 PM Steve Ebersole <steve at hibernate.org>
> wrote:
> >>>
> >>> One goal of the redesign is to build more friendly, easy-to-follow
> >>> contract for access to this metadata at runtime (legacy persister
> state).
> >>> Rather than accessing pieces of information pertaining to attributes
> across
> >>> many, many arrays I wanted an array of a composite representation of
> these
> >>> attributes.  JPA defines it this way, so on some level you'd think it
> would
> >>> be pretty straightforward to move this direction.  The major
> pain-point I
> >>> have been facing is that JPA does not define "mapping information" at
> all
> >>> in its Metamodel/Types.  The main place this comes to a head is
> >>> EmbeddableType, especially given access to it directly on Metamodel *by
> >>> class*.  In JPA terms that return has to model the Embeddable (no
> mapping
> >>> info) rather than the Embedded.  And then further when we
> >>> expose EmbeddableType's attributes we have the same problem continued
> >>> because the context/root is the embeddable rather than the embedded.
> >>> Hopefully this makes sense, but as an example consider (using a
> "component
> >>> safe NamingStrategy):
> >>>
> >>> @Entity
> >>> class Store {
> >>>    ...
> >>>    @Embedded
> >>>    Address headquartersAddress;
> >>>    @Embedded
> >>>    Address locationAddress;
> >>> }
> >>>
> >>> @Embeddable
> >>> class Address {
> >>>    String streetAddress;
> >>>    @Embedded
> >>>    PostalCode postalCode;
> >>>    ...
> >>> }
> >>>
> >>> @Embeddable
> >>> class PostalCode {
> >>>    String zip;
> >>>    String plus4;
> >>>    @ManyToOne
> >>>    City city;
> >>> }
> >>>
> >>> Then consider that JPA frames access to this information as:
> >>>
> >>> EmbeddableType<Address> addrType = metamodel.embeddable( Address.class
> );
> >>>
> >>> Because it is generic to the Address embeddable, we have no access to
> the
> >>> specific embedded mapping info.  And if we follow this access down
> further,
> >>> it also means the same for accessing the attributes of that
> EmbeddableType<Address>.
> >>> For example, accessing the "postalCode.zip" from the
> EmbeddableType<Address>
> >>> we'd have no ability to resolve whether that maps to
> "headquartersAddress_postalCode_zip"
> >>> or "locationAddress_postalCode_zip".  And of course, as an ORM we need
> >>> access to that mapping information :)
> >>>
> >>> Essentially that is the crux of the difficulty I have at the moment.
> >>>
> >>> I know we could get around this by splitting (or keeping split) the
> >>> notions of ORM Type and JPA Type, but I would like to avoid that : this
> >>> unification is going to be important to the SQM Criteria support.
> >>>
> >>> So the question becomes how to best handle exposing an "Attribute" with
> >>> mapping information as well as an "Attribute" without mapping
> information.
> >>>
> >>> I will be working on some proposals for ways to do this over the next
> week
> >>> or so.  And maybe y'all see a solution easier than I do (I fear I may
> not
> >>> be seeing the forest through the trees atm).
> >>>
> >>>
> >>> On Thu, Jul 21, 2016 at 7:49 AM Steve Ebersole <steve at hibernate.org>
> >>> wrote:
> >>>
> >>>> I am working on a larger response to some current challenges, but
> here is
> >>>> a quick response to your specific points...
> >>>>
> >>>> On Wed, Jul 20, 2016 at 12:50 PM Emmanuel Bernard <
> emmanuel at hibernate.org>
> >>>> wrote:
> >>>>
> >>>>>
> >>>>> BasicType does not handle multiple column and compositeType is the
> >>>>> mebedded case. How would multi-column types would be handled?
> >>>>
> >>>> In terms of what exactly?  Assuming you mean access to the JDBC
> >>>> descriptors, that is still being determined.  At the moment there is
> no
> >>>> single Type-level access to this information.  Each specific Type
> >>>> sub-interface defines access differently.  I am not a fan of that that
> >>>> aspect.  The other approach is to define a plural form on Type
> >>>> (Type#getColumnMappings), and BasicType would just ensure that there
> is
> >>>> just one.
> >>>>
> >>>>
> >>>> Why do you need to ”unscope" the TypeConfiguration? What do you gain
> from
> >>>>> it? I’m trying to picture a reuse use case?
> >>>>
> >>>> Functionally we do not gain anything.  I was just trying to be
> balanced.
> >>>> We injected the SF into the TypeConfiguration, I wanted to un-inject
> it as
> >>>> well for 2 reasons:
> >>>>
> >>>>   1. release the reference to the SF
> >>>>   2. prepare the TypeConfiguration for binding to another SF.
> >>>>
> >>>> The only use case I had in mind was tests where we occasionally build
> >>>> multiple SF instances from a single Metadata.
> >>>>
> >>>>
> >>>> Methods of Type needing Session: I used to call them passing null in
> some
> >>>>> old code and hoping for the best. Are the reasons for using Session
> still
> >>>>> present? Would be nice to get rid of that.
> >>>>
> >>>> This is only ever needed (sometimes) from EntityType.  I guess it
> depends
> >>>> which specific method(s) you are asking about.  For some (reading,
> writing)
> >>>> yes I think we will continue to need the Session: it is used for
> access to
> >>>> JDBC as well as other needed interactions with the Session/PC
> (scheduling
> >>>> ids for batch load, etc).  For other methods, maybe not.
> >>>>
> >>>>
> >>>> On the genericization of Type, it would be extremely nice indeed for
> OGM,
> >>>>> but it would require to genericize SqlTypeDescriptor and its methods
> >>>>> essentially. Not necessarily super trivial.
> >>>>
> >>>> I understand that.  It is not a primary goal for me tbh.  But if we
> can
> >>>> get a decent design for the ORM case and can see an easy way to
> extend this
> >>>> to OGM without negatively impacting ORM I am all for it.  Given the
> >>>> delegation to Binder and Extractor I think this will be doable,
> although I
> >>>> assume we will need some parameterized param object to make this
> work.  The
> >>>> paam object would give us access to "JDBC services" in ORM and
> something
> >>>> else in OGM.
> > _______________________________________________
> > hibernate-dev mailing list
> > hibernate-dev at lists.jboss.org
> > https://lists.jboss.org/mailman/listinfo/hibernate-dev
>
>


More information about the hibernate-dev mailing list