Question

I have an attribute (creationTimestamp in MetaData) which I annotated to load lazy. No I need it for one entity to load eager. I tried it with fetch graphs without success. Is there a JOIN FETCH like feature I can use to FETCH it in the query?

I am using Wildfly with the bundled hibernate.

When I try to fetch it with a fetch graph I get the exception that hibernate can't find the id field. This field is in entity base (protected).

@NamedQueries({ @NamedQuery(name = ChatMessage.FIND_BY_CHAT_TIME, query = "SELECT m FROM ChatMessage m "
        + "WHERE m.chat=:chat "
        + "AND m.creationTimestamp > :index ORDER BY m.creationTimestamp") })
@NamedEntityGraph(
        name = ChatMessage.GRAPH_FETCH_ALL,
        attributeNodes = {@NamedAttributeNode("id"), @NamedAttributeNode("player"), @NamedAttributeNode("text"), @NamedAttributeNode("creationTimestamp")}
    )
public class ChatMessage extends EntityBase {

@MappedSuperclass
public abstract class EntityBase extends MetaData {
    private static final long serialVersionUID = -5579667581450362176L;

    public static final String FETCH_GRAPH_HINT = "javax.persistence.fetchgraph";

    @Id
    @Column(length = 36)
    protected String id = java.util.UUID.randomUUID().toString();

@MappedSuperclass
public class MetaData implements Serializable {
    private static final long serialVersionUID = 8870539357817188030L;

    @Version
    private long version;

    @Temporal(TemporalType.TIMESTAMP)
    @Column(nullable = false, updatable = false)
    @Basic(fetch=FetchType.LAZY)
    protected Calendar creationTimestamp;

    @Temporal(TemporalType.TIMESTAMP)
    @Column(nullable = false)
    @Basic(fetch=FetchType.LAZY)
    private Calendar updateTimestamp;

Leads to this exception:

Caused by: java.lang.IllegalArgumentException: Unable to locate Attribute  with the the given name [id] on this ManagedType [ChatMessage]
    at org.hibernate.jpa.internal.metamodel.AbstractManagedType.checkNotNull(AbstractManagedType.java:144)
    at org.hibernate.jpa.internal.metamodel.AbstractManagedType.getDeclaredAttribute(AbstractManagedType.java:137)
    at org.hibernate.jpa.graph.internal.EntityGraphImpl.resolveAttribute(EntityGraphImpl.java:139)
    at org.hibernate.jpa.graph.internal.AbstractGraphNode.buildAttributeNode(AbstractGraphNode.java:119)
    at org.hibernate.jpa.graph.internal.AbstractGraphNode.addAttribute(AbstractGraphNode.java:114)
    at org.hibernate.jpa.internal.EntityManagerFactoryImpl.applyNamedAttributeNodes(EntityManagerFactoryImpl.java:279)
    at org.hibernate.jpa.internal.EntityManagerFactoryImpl.applyNamedEntityGraphs(EntityManagerFactoryImpl.java:266)
    at org.hibernate.jpa.internal.EntityManagerFactoryImpl.<init>(EntityManagerFactoryImpl.java:173)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:865)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:843)
    at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl.withTccl(ClassLoaderServiceImpl.java:399)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:842)
    at org.hibernate.jpa.HibernatePersistenceProvider.createEntityManagerFactory(HibernatePersistenceProvider.java:73)

Is there a way to fetch the property like a fetch join? Or do I have to reference the fetch graph in another way?

best regards, m

Was it helpful?

Solution

Looks like properties of subclasses have to be references a different way:

@NamedEntityGraph(
        name = ChatMessage.GRAPH_FETCH_ALL,
        attributeNodes = {@NamedAttributeNode("player"), @NamedAttributeNode("text")}
        , subgraphs={@NamedSubgraph(name="MetaData.subgraph", attributeNodes={@NamedAttributeNode("id"), @NamedAttributeNode("creationTimestamp")})}
    )
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top