JPA EntityGraph based on meta model containing MappedSuperclass not possible?
Asked Answered
P

1

4

I'm trying to use the type safe method EntityGraph.addAttributeNodes(Attribute<T, ?> ... attribute) for constructing my entity graph. I have a type hierarchy with a @MappedSuperclass that basically looks like this:

@MappedSuperclass
public abstract class BaseEntity
{
    @Id
    private int dbid;
}

@Entity
public class Entity extends BaseEntity
{
    private String someAttribute;
}

EclipseLink creates this meta model:

@Generated(value="EclipseLink-2.5.2.v20140319-rNA", date="2015-08-07T10:46:31")
@StaticMetamodel(BaseEntity.class)
public abstract class BaseEntity_ { 
    public static volatile SingularAttribute<BaseEntity, Integer> dbid;
}

@Generated(value="EclipseLink-2.5.2.v20140319-rNA", date="2015-08-07T10:46:31")
@StaticMetamodel(Entity.class)
public class Entity_ extends BaseEntity_ {
    public static volatile SingularAttribute<Entity, String> someAttribute;
}

The problem is that I cannot refer to the dbid attribute with the entity graph API:

EntityGraph<Entity> graph = em.createEntityGraph( Entity.class );
graph.addAttributeNodes( Entity_.dbid ); // does not compile: "The method addAttributeNodes(String...) in the type EntityGraph<Entity> is not applicable for the arguments (SingularAttribute<BaseEntity,Integer>)"

For this to work, wouldn't the method signature need to look like this: EntityGraph.addAttributeNodes(Attribute<? super T, ?> ... attribute)? Is this a shortcoming of the specification or am I overlooking something?

It seems to me that this is a problem related to the one described here. As the author of that question points out, the Criteria API get method for singular attributes does indeed use ? super X to define the type parameter.

But even when I add the someAttribute node, there's still this somewhat ugly warning, which I presume can only be suppressed at best:

graph.addAttributeNodes( Entity_.someAttribute ); // generates warning: "Type safety: A generic array of Attribute<Entity,?> is created for a varargs parameter"
Percale answered 7/8, 2015 at 10:5 Comment(2)
i guess i have a similar problem: there is Path.get(SingularAttribute<? super X, Y> attribute) but Path.get(PluralAttribute<X, C, E> collection); -just to be used in Predicates. How you worked around this issue?Essentialism
I'm afraid I don't remember exactly, but I believe I gave up on the type-safe construction of entity graphs in this case and resorted to the non-safe way with @NamedEntityGraph on the entities.Marijo
P
5

I'd agree.

Clearly if you changed your code to

EntityGraph<BaseEntity> graph = em.createEntityGraph(BaseEntity.class);
graph.addAttributeNodes(BaseEntity_.dbid );

then it would compile. The problem does indeed seem to be in the spec/API where it has EntityGraph's generic type being applied to the addAttributeNodes argument (hence not allowing superclass fields). Yes, it does say that "T" is the type of the root entity, but that can't mean that they expect people to always use the MappedSuperclass?

I'd also confirm that by using "? super T" for the Attribute generic type fixes it (taking a javax.persistence jar source and modifying/rerunning).

I raised it as an issue on JPA, not that I'd recommend holding breath for an update

Peekaboo answered 7/8, 2015 at 13:24 Comment(1)
Thanks for bringing this forward to the spec guys.Marijo

© 2022 - 2024 — McMap. All rights reserved.