Francisco Hidalgo
Francisco Hidalgo

Reputation: 1

How to do a Inner-Join in JPA Criteria?

I'm using Netbeans to program a webservice REST that returns a JSON response, I am also using JPA Criteria to create the querys. I have two Entities that looks like this:

public class User implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @Basic(optional = false)
    @NotNull
    @Column(name = "id_user")
    private Integer idUser;
    @Size(max = 45)
    @Column(name = "username")
    private String username;
    @Size(max = 45)
    @Column(name = "password")
    private String password;
    @Size(max = 45)
    @Column(name = "email")
    private String email;
    @OneToMany(mappedBy = "idUser")
    private Collection<Comment> commentCollection;

public class Comment implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @Basic(optional = false)
    @NotNull
    @Column(name = "id_comment")
    private Integer idComment;
    @Column(name = "id_thesis")
    private Integer idThesis;
    @Size(max = 250)
    @Column(name = "comment")
    private String comment;
    @Column(name = "cdate")
    @Temporal(TemporalType.DATE)
    private Date cdate;
    @JoinColumn(name = "id_user", referencedColumnName = "id_user")
    @ManyToOne
    private User idUser;
}

Both entities with sets and gets. I want to do a query like this:

SELECT * FROM Comments c INNER JOIN User u WHERE c.id_user = u.id_user;

but in the JPA Criteria language, I've had many problems trying to make it work but i don't get it yet.

This is the code that I'm using for the join

AbstractFacade.java

public Join<User, Comment> getCommentInfo() { 
    CriteriaBuilder cb = getEntityManager().getCriteriaBuilder();
    CriteriaQuery q = cb.createQuery();
    Root<User> r = q.from(User.class);
    Join<User, Comment> j = r.join("commentCollection", JoinType.INNER);
    Query query = getEntityManager().createQuery(q);  

    return (Join<User, Comment>) query.getResultList();
}

UserFacadeREST.java

@GET
@Path("test")
@Produces({"application/json"})
public Join<User, Comment> getCommentInfoREST() {
    return getCommentInfo();        
}

This error is shown when I test the method:

java.util.Vector cannot be cast to javax.persistence.criteria.Join

Please help me with that, I do not know if the sentence join is wrong or how to solve the cast properly.

Edit: I add the next lines to the getCommentInfo() method to see the content of the list.

    q.select(j.get("username"));

    List results = query.getResultList();

    Iterator iter = results.iterator();
    while (iter.hasNext()){
        System.out.println(iter.next());
    }

Error: The attribute [username] is not present in the managed type [EntityTypeImpl@1000979996:Comment.

Upvotes: 0

Views: 2897

Answers (1)

NoDataFound
NoDataFound

Reputation: 11969

In the case of getResultList(), the javadocs state that it returns an java.util.List (see here: http://docs.oracle.com/javaee/5/api/javax/persistence/Query.html#getResultList%28%29 ), that Vector implements.

The result type, aka what's in the list, depends on the criteria projection or, in a JPQL Query, of the from statement.

In your case, because you don't do projection, I think it should return a List<User>.

For your information, and if you are using JPA 2.0, you can also use TypedQuery which could avoid that (ugly !) cast : http://www.javabeat.net/typedquery-jpa-2/

Upvotes: 1

Related Questions