samedi 30 mai 2015

Criteria API and Entity Graph

I have two entities with unidirectional lazy relations. And one of them has a named entity graph. Here are the entities (getters and setter are not listed due to readability):

    @Entity
    @NamedEntityGraph (
            name = "Sms.fetchSims",
            attributeNodes = {
                    @NamedAttributeNode("sim")
            }
    )
    public class Sms {
        @Id
        @GeneratedValue (strategy = GenerationType.AUTO)
        private Long id;
        @NotNull
        private Timestamp date;
        @NotNull
        private String sender;
        @NotNull
        private String content;

        @NotNull
        private Direction direction;

        @NotNull
        @ManyToOne (fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
        private Sim sim;
    }

    @Entity
    public class Sim {
        @Id
        @GeneratedValue (strategy = GenerationType.AUTO)
        private long id;

        @NotNull
        private long IMSI;

        private String MSISDN;
        private String provider;
        private Timestamp lockedDate;
    }

When I fetch any sms using the entity manager find() method with this entity graph, I get an sms with a sim. But i want to be able to find smses by sim id. That's why i created a criteria api query for that purpose.

    CriteriaBuilder cb = entityManager.getCriteriaBuilder();

    EntityGraph eg = entityManager.getEntityGraph("Sms.fetchSims");

    CriteriaQuery<Sms> cq = cb.createQuery(Sms.class);
    Root<Sms> smses = cq.from(Sms.class);
    Join<Sms, Sim> sims = smses.join(Sms_.sim);
    cq.where(cb.equal(sims.get(Sim_.id), simId));
    cq.orderBy(cb.desc(smses.get(Sms_.date)));

    return entityManager
        .createQuery(cq)
        .setHint("javax.persistence.fetchgraph", eg)
        .setMaxResults(1000)
        .getResultList();

As you see, i set the entity graph here using a setHint method of the typed query, but sim is never fetched, it's fields are not even listed in the result sql. What could i do to make entity graph work with criteria api?

I know I can typecast smses.fetch(Sms_.sim) to Join, but i get ugly warnings, and this method looks like a dirty hack to me.

I'm working with hibernate and wildfly-8.2.0.Final application server.

Aucun commentaire:

Enregistrer un commentaire