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(a)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.