I have the following class (getters/setters are omitted): {code:java} @MappedSuperclass public class Position<T> { @Id @Column(name = "id", columnDefinition = "uuid") private UUID id;
@Column(name = "value") private Long value;
@OneToOne(optional = false, fetch = FetchType.LAZY) @PrimaryKeyJoinColumn private T entity;
... } {code}
And some subclasses: {code:java} @Table(schema = "test", name = "category_position") @NamedEntityGraph(name = CATEGORY_POSITION__FETCH_ALL, includeAllAttributes = true) public class CategoryPositionEntity extends Position<CategoryEntity> { public static final String CATEGORY_POSITION__FETCH_ALL = "CategoryPosition.fetchAll"; } {code}
{code:java} @Table(schema = "test", name = "vod__attribute_position") @NamedEntityGraph( name = VOD_ATTRIBUTE_POSITION__FETCH_ENTITY_WITH_TAGS, attributeNodes = @NamedAttributeNode(value = "entity", subgraph = "entity.tags"), subgraphs = @NamedSubgraph( name = "entity.tags", attributeNodes = @NamedAttributeNode(value = "tags") ) ) public class VodAttributePositionEntity extends Position<VodAttributeEntity> { public static final String VOD_ATTRIBUTE_POSITION__FETCH_ENTITY_WITH_TAGS = "VodAttributePosition.fetchEntityWithTags"; } {code}
Here is CategoryEntity and VodAttributeEntity:
{code:java} @Entity @Table(schema = "tdatv", name = "category") public class CategoryEntity {
@Id @Column(name = "id", columnDefinition = "uuid") @GeneratedValue(generator = "UUID") @GenericGenerator( name = "UUID", strategy = "org.hibernate.id.UUIDGenerator" ) private UUID id;
@Column(name = "name") private String name;
@Column(name = "video_block_title") private String videoBlockTitle;
@Column(name = "featured") private Boolean featured;
... } {code}
{code:java} @Entity @Table(schema = "test", name = "vod__attribute") public class VodAttributeEntity {
@Id @Column(name = "id", columnDefinition = "uuid") @GeneratedValue(generator = "UUID") @GenericGenerator( name = "UUID", strategy = "org.hibernate.id.UUIDGenerator" ) private UUID id;
@Column(name = "name") private String name;
@OneToMany(cascade = {PERSIST, MERGE, REMOVE}, orphanRemoval = true, fetch = EAGER) @JoinColumn(name = "attribute_id", nullable = false, insertable = false, updatable = false) @OrderBy("name") private List<VodTagEntity> tags;
... } {code}
And VodTagEntity:
{code:java} @Entity @Table(schema = "test", name = "vod__tag") public class VodTagEntity {
@Id @Column(name = "id", columnDefinition = "uuid") @GeneratedValue(generator = "UUID") @GenericGenerator( name = "UUID", strategy = "org.hibernate.id.UUIDGenerator" ) private UUID id;
@Column(name = "name") private String name;
@Column(name = "attribute_id", columnDefinition = "uuid") private UUID attributeId;
@ElementCollection(fetch = FetchType.LAZY) @CollectionTable( schema = "test", name = "vod__link_video_tag", joinColumns = {@JoinColumn(name = "tag_id")} ) @Cascade(REMOVE) @Column(name = "video_id") private List<UUID> videoIds; } {code}
After upgrading from 5.2.12 to 5.4.1 I get the following exception when creating Hibernate SessionFactory (through JPA): {{ java.lang.ExceptionInInitializerError Caused by: javax.persistence.PersistenceException: [PersistenceUnit: sandbox] Unable to build Hibernate SessionFactory at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.persistenceException(EntityManagerFactoryBuilderImpl.java:1015) at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:941) at org.hibernate.jpa.HibernatePersistenceProvider.createEntityManagerFactory(HibernatePersistenceProvider.java:56) at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:79) at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:54) at Test.<clinit>(Test.java:7) Caused by: java.lang.IllegalArgumentException: Unable to locate Attribute with the the given name [featured] on this ManagedType [VodAttributeEntity] at org.hibernate.metamodel.model.domain.internal.AbstractManagedType.checkNotNull(AbstractManagedType.java:147) at org.hibernate.metamodel.model.domain.internal.AbstractManagedType.getAttribute(AbstractManagedType.java:118) at org.hibernate.graph.spi.GraphImplementor.findOrCreateAttributeNode(GraphImplementor.java:98) at org.hibernate.graph.internal.AbstractGraph.addAttributeNode(AbstractGraph.java:175) at org.hibernate.metamodel.internal.MetamodelImpl.applyNamedAttributeNodes(MetamodelImpl.java:380) at org.hibernate.metamodel.internal.MetamodelImpl.applyNamedSubgraphs(MetamodelImpl.java:404) at org.hibernate.metamodel.internal.MetamodelImpl.applyNamedAttributeNodes(MetamodelImpl.java:383) at org.hibernate.metamodel.internal.MetamodelImpl.applyNamedEntityGraphs(MetamodelImpl.java:367) at org.hibernate.metamodel.internal.MetamodelImpl.initialize(MetamodelImpl.java:284) at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:294) at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:462) at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:938) ... 4 more Exception in thread "main" }}
Bootstrap code:
{code:java} public class Test { private static EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("sandbox");
public static void main(String... args) { EntityManager manager = entityManagerFactory.createEntityManager(); } } {code}
persistence.xml contains only minimal DB connection properties, and there is only hibernate-core and jdbc driver as maven project dependencies.
I did some debugging and found out that AttributeNodeImpl.internalMakeSubgraph(Class<S> subType) method behavior is changed (after upgrading from 5.2.12). Seems like it loose superclass generic information and uses meta information from Position class, and for some reason it's "entity" property has VodAttributeEntity type for both VodAttributePositionEntity and CategoryPositionEntity.
Is it desired behavior? I didn't notice any restrictions on using generic superclass as mappedsuperclass for entity subgraph in JPA 2.2 spec.
I attached test maven project that reproduce the problem. [^sandbox.zip] |
|