Java – JPA (hibernate): error using @ embeddedid in generic @ mappedsuperclass
I am currently defining JPA entities (many compound keys, but also single column keys) for legacy databases I created the following entity superclasses:
@MappedSuperclass public abstract class AbstractEntity<ID extends Serializable> { public abstract ID getId(); public abstract void setId(ID id); }
Then there is the superclass of composite key (and the superclass of long primary key, which is not listed here):
@MappedSuperclass public abstract class AbstractEmbeddedIdEntity<ID extends Serializable> extends AbstractEntity<ID> { @EmbeddedId private ID id; public AbstractEmbeddedIdEntity() { id = newId(); } @Override public ID getId() { return id; } @Override public void setId(ID id) { this.id = id; } protected abstract ID newId(); }
Finally, such specific entities:
@Entity @Table(name = "firstEntity") public class FirstEntity extends AbstractEmbeddedIdEntity<FirstEntityId> { public FirstEntity() { } @Embeddable public static class FirstEntityId implements Serializable { @Column(name = "firstId") private String firstId; public FirstEntityId() { } @Override public boolean equals(Object obj) { if (obj == this) { return true; } if (!(obj instanceof FirstEntityId)) { return false; } FirstEntityId other = (FirstEntityId) obj; return Objects.equals(firstId,other.firstId); } @Override public int hashCode() { return Objects.hash(firstId); } } @Override protected FirstEntityId newId() { return new FirstEntityId(); } }
The problem now is that if I have such multiple entities and try to access the ID attribute of the entity (currently using spring boot, such as findbyidfirstid (string firstid)), an exception will be thrown:
java.lang.IllegalArgumentException: Unable to locate Attribute with the the given name [firstId] on this ManagedType [unkNown]
I debugged this and found that in Hibernate, the metamodel maps all my entities to the same mappedsupplier class instance During application startup, the @ embeddedid returned by newid () is set to mappedsupplerclass, overwriting the ID of the previous entity. Therefore, in the end, all entities are mapped to the same mappedsupplerclass, but mappedsupplerclass only has the @ embeddedid of the last entity
In the above example, accessing the ID attribute failed because the @ embeddedid of the last entity has no attribute named "firstid" (it has been overwritten by the ID attribute of the last entity)
Now I want to know if my method is wrong, if I miss anything, or this may be a problem with Hibernate?
A complete example of using spring boot available on GitHub Run with MVN spring boot: run
Solution
This looks like a bug in Hibernate, so I created a ticket in Hibernate Bug Tracker As a solution, I now define the ID attribute (@ embeddedid) in the concreate entity class instead of the abstract superclass