简体   繁体   中英

JPA creating a CriteriaQuery for a JOIN statement with attributes in an embedded primary key

I'm having some trouble creating a TypedQuery for a JOIN statement using JPA, hoping someone can point me in the right direction.

As an example, suppose I have a table, Person, with a composite primary key (PERSONID, FISRTNAME, LASTNAME):

CREATE TABLE Person (
PERSONID int NOT NULL,
FIRSTNAME varchar2(255) NOT NULL,
LASTNAME varchar2(255) NOT NULL,
AGE int,
CONSTRAINT PK_PERSON PRIMARY KEY (PERSONID, FIRSTNAME, LASTNAME)
);

I can then use JPA to generate an entity class with it's composite primary key, which would look something like this:

@Entity
public class Person implements Serializable {
    private static final long serialVersionUID = 1L;
    private PersonPK id;
    private int age;
    //constructor and getters and setters...
}

@Embeddable
public class PersonPK implements Serializable {
    private static final long serialVersionUID = 1L;
    private int personid;
    private String firstname;
    private String lastname;
    //constructor and getters and setters...
}

Let's suppose also I have another table, Order, also with a composite primary key (PERSONID, FIRSTNAME; LASTNAME, PRODUCTID):

CREATE TABLE Order (
PERSONID int NOT NULL,
FIRSTNAME varchar2(255) NOT NULL,
LASTNAME varchar2(255) NOT NULL,
PRODUCTID int NOT NULL,
DESCRIPTION varchar2(255),
CONSTRAINT PK_ORDER PRIMARY KEY (PERSONID, FIRSTNAME, LASTNAME, PRODUCTID)
);

And JPA would generate some similar looking entity classes:

@Entity
public class Order implements Serializable {
    private static final long serialVersionUID = 1L;
    private OrderPK id;
    private String description;
    //constructor and getters and setters...
}

@Embeddable
public class OrderPK implements Serializable {
    private static final long serialVersionUID = 1L;
    private int personid;
    private String firstname;
    private String lastname;
    private int productid
    //constructor and getters and setters...
}

Okay, so probably not the most sensible schema but it works for my example. So, this is the SQL statement I'd like to reproduce:

SELECT * 
FROM Person
INNER JOIN Order
ON Person.PERSONID = Order.PERSONID
AND Person.FIRSTNAME = Order.FIRSTNAME
AND Person.LASTNAME = Order.LASTNAME;

So probably not in this schema but for my project in Oracle SQL it produces the results I want. So, here's my question, how do I create this query using a JPA?

This is what I have tried so far:

EntityManagerFactory emf = Persistance.createEntityManagerFactory("persistenceunitname");
EntityManager em = emf.createEntityManager();
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Person> query = cb.createQuery(Person.class);
Root<Person> person = query.from(Person.class);
Join<Person, Order> orders = person.join("personid"); //the problem is with this line, explained in more detail below
query.multiselect(orders); // not sure if this is correct
TypedQuery<Person> q = em.createQuery(query); // not sure if this is correct
List<Person> results = q.getResultList(); // not sure if this is correct

The problem I have found after following some online tutorials, is with the line:

Join<Person, Order> orders = person.join("personid");

because the attribute personid is inside the embeddable class PersonPK, and not in Person, due to it being a composite primary key.

Obviously, supposing "personid" correctly identifies the attribute in the primary key, this would only create a join statement on personid, and not on the firstname nor the lastname.

So, my question is, how can I correctly create a TypedQuery statement that will create the JOIN statement as specified above?

The join() method is also used to navigate to embedded attributes:

Join<Person, Order> orders = person.join("id").join("personid")

Source: https://docs.jboss.org/hibernate/orm/5.6/userguide/html_single/Hibernate_User_Guide.html#criteria-from-join

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM