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(a)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(a)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(a)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(a)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(a)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(a)lists.jboss.org
>
https://lists.jboss.org/mailman/listinfo/hibernate-dev