[hibernate-dev] Cache key containing composite ID with a many-to-one

Gail Badner gbadner at redhat.com
Thu Dec 5 15:19:17 EST 2019


Hi Steve,

I like your ideas about loading an entity with multiple ID attributes
without @IdClass. It's much nicer than passing an instance of the entity
with ID attributes initialized to Session#get.

Getting back to the cache issue -- it sounds like disassembling the ID is
worth pursuing.

Please confirm...

Thanks,
Gail

On Thu, Dec 5, 2019 at 9:33 AM Steve Ebersole <steve at hibernate.org> wrote:

> > JPA does not allow mixing of @IdClass and @EmbeddedId.  But I think
>> that's a valid option.  In fact in our original work on 6 where we
>> completely replaced the mapping model (persisters) i had added support for
>> this.  We could add an improvement to pull this feature to 6 proper?
>>
>> There would be some rough edges (what would
>> org.hibernate.Session#getIdentifier return, the embedded id or the idclass?
>> What would Session.load accept? What would be the declared type of the ID
>> in JPA Criteria?). But that could be a valuable feature for people who
>> really want composite IDs. And it could solve the caching problem.
>> However, if we need to solve the caching problem in ORM 5 and are not in
>> a position to declare that caching isn't supported for such identifiers...
>> then we'll have to work on some hack in ORM 5. So maybe it's not a priority
>> in ORM 6.
>>
>
> `Session#getIdentifier` would return the embedded-id, imo.  The
> embedded-id is the "real" id.  The id-class is just a simplified "syntactic
> sugar" used only for an alternative form of loading.  In fact for an entity
> with an id-class you can load using either approach, though the legacy form
> of loading an entity with a non-aggregated composite id is truly painful.
>
> Just spit-balling, one option would be to expose a even more simplified
> loading for these entities using `Session#byId` (or a new similar method)
> allowing specifying the simplified, basic "maps-id" values for the load.
> Just for illustration, something like:
>
> session.byCompositeId( EntityWithCompositeId.class )
>     .using( "idAttribute1", "idAttribute1-value" )
>     .using( "keyManyToOne", "keyManyToOne-basic-id-value" )
>     ...
>     .load();
>
> That's geared toward non-aggregated composite id cases, though really it
> could be available in aggregated composite id cases as well.
>
> We could also allow a form in normal load-by-id using a Map maybe?  I only
> mention this as even though its still a "new feature", it does not require
> any API changes or new APIs.
>
> final Map idValues = new HashMap();
> idValues.put( "idAttribute1", "idAttribute1-value" );
> idValues.put( "keyManyToOne", "keyManyToOne-basic-id-value" );
> ...
> session.get( EntityWithCompositeId.class, idValues );
>
> Or even an "array Map" option to avoid the Map instantiation:
>
> final Object[] idValues = new Object[] {
>     "idAttribute1", "idAttribute1-value",
>     "keyManyToOne", "keyManyToOne-basic-id-value",
>     ...
> };
> assert idValues.length %2 == 0;
> session.get( EntityWithCompositeId.class, idValues );
>
> Of course, if the embedded-id could also have an id-class you'd use that.
>
> I'd like to see all of these as options btw, not one-or-the-other.
> Though I'm fine if no-one else likes the `Session#byCompositeId` idea.
> It was just a spur-of-the-moment idea.
>


More information about the hibernate-dev mailing list