Composite IDs with a null property/field
by Gail Badner
Currently, there is no way to load an entity that exists in the database
with a composite ID, if one of the composite ID columns is null.
This behavior is due to this code in ComponentType#hydrate:
https://github.com/hibernate/hibernate-orm/blob/master/hibernate-core/src...
Basically, if any field/property in a composite ID is null, Hibernate
assumes the entire ID is null. An entity cannot have a null ID, so it
returns null for the entity result.
I believe that Hibernate does allow a primary key column to be nullable.
TBH, it seems strange to have a property in a composite ID that can be
null. If it can be null, it seems that the property could be removed from
the composite key.
I don't see anything in the spec about a requirement that all composite ID
fields/properties must be non-null. Am I missing something?
The code I referenced above is 13 years old. Does anyone have insight into
why Hibernate does this?
Thanks,
Gail
5 years
Hibernate Search 6.0.0.Beta3 released
by Yoann Rodiere
Hello,
We just published Hibernate Search 6.0.0.Beta3.
This release mainly brings schema improvements, deep customization of
Elasticsearch search requests, more powerful bridge definitions, and
restores features such as the search query timeouts.
It also includes upgrades to Lucene 8.3.0, Elasticsearch 7.5 and Hibernate
ORM 5.4.10.Final.
For more information, see our blog:
https://in.relation.to/2019/12/16/hibernate-search-6-0-0-Beta3/
Yoann Rodière
Hibernate Team
yoann(a)hibernate.org
5 years
IdClass superclasses
by Gail Badner
Hi,
Suppose we have the following:
public class CompositeKey implements Serializable {
private Long id1;
private Long id2;
public CompositeKey(Long id1, Long id2) {
super();
this.id1 = id1;
this.id2 = id2;
}
...
}
public class InheritedKey extends CompositeKey {
private Long id3;
public InheritedKey(Long id1, Long id2, Long id3) {
super(id1, id2);
this.id3 = id3;
}
...
}
@Entity(name = "IKE")
@IdClass(InheritedKey.class)public class InheritedKeyEntity {
@Id
private Long id1;
@Id
private Long id2;
@Id
private Long id3;
private String name;
...
}
Currently, Hibernate does not include InheritedKey#id3 in
InheritedKeyEntity's composite key unless InheritedKey is annotated with
@MappedSuperclass.
I think there are some improvements that can be made.
1) As you can see, the entity, itself, has all of the ID fields annotated.
An improvement would be for Hibernate to ensure that all mapped ID
properties have been detected, and throw an exception if this is not the
case.
2) A class used as an IdClass does not need any annotations (as opposed to
a class used for an EmbeddedId class, which requires {{@Embeddable}}).
Since the class used as an IdClass does not need to be annotated, it seems
kind of strange that its superclass would need to be annotated with
{{@MappedSuperclass}} in order for its fields/properties to be persistent.
Since the field/property names must match what is annotated in an IdClass,
it is clear that the field/property in a superclass is intended to be an
ID. Perhaps we could make annotating the superclass with
{{@MappedSuperclass}} optional?
Opinions?
Thanks,
Gail
5 years
Cache key containing composite ID with a many-to-one
by Gail Badner
When an entity is cached with a composite ID containing a many-to-one
association, the cache key will contain the many-to-one associated entity.
If the associated entity is not enhanced, then it could be an uninitialized
proxy.
I've created a test case [1] that illustrates this using Infinispan. The
test case is for 5.1 branch, since hibernate-infinispan is still included
in that branch. The same would happen for master as well.
Aside from the obvious issue with increased memory requirements to store an
entity, there are other problems as well.
What I've found so far is that caching a key with an uninitialized entity
proxy can cause some big problems:
1) A lookup will never find this key unless the lookup is done with a cache
key containing the same entity proxy instance.
2) Calling EntityManager#find with a composite ID containing a detached
uninitialized entity proxy will result in a LazyInitializationException.
This does not happen with second-level cache disabled.
3) Calling EntityManager#find with a composite ID containing a managed
uninitialized entity proxy will result in the proxy being initialized. This
does not happen with second-level cache disabled.
I have not looked into what happens when the associated entity is enhanced
and uninitialized (i.e., enhancement-as-proxy).
IIUC, disassembling the ID that gets stored in the cache key would be far
more efficient, and would avoid these issues. We would only want to do this
when a composite ID contains an association. This would require changes in
some SPIs though, to account for the disassembled ID type.
I've been discussing necessary changes with Scott to cache a
disassembled ID. Before we get too far down this road, I'd like to get some
feedback.
In the first place, should an entity instance be stored in a cache key?
Is disassembling primary keys that contain an association the appropriate
way to go? If so, I'll continue with a POC for doing this.
Thanks,
Gail
[1]
https://github.com/gbadner/hibernate-core/blob/753e36edf5137296d28b2a07ce...
5 years