Composite Primary key in JPA

2019-07-20 11:14发布

问题:

The EmbeddedId or IdClass annotation is used to denote a composite primary key. How can i use composite primary key without ( EmbeddedId or IdClass ) ?

If it is possible to use composite primary key without ( EmbeddedId or IdClass ) then how can i use EntityManager.find( Entity Class , Object primaryKey) method to find entity in case of composite primary key(Multiple Primarykey) (because of no IdClass or EmbeddedId) .

EclipseLink take List of pk in the find() operation but if composite pk key defined in example -

    Entity Person {
           @Id 
           String username;
           @Id
           String emailId;
           @Basic
           String firstName;
           @Basic
           String lastName;
    }

    List list = new ArrayList();
    list.add(${username});  //Run time value
    list.add(${emailId});   //Run time value

then EnitityManager.find(list) will take these arguments , is i am right?

If i am assuming correct then how will EnitityManager.find() operation will know that List 1st argument is username or emailId pk value (means sequence of composite pk fields value)

回答1:

You should be able to use a List with the find() operation in EclipseLink.



回答2:

Let me give my thoughts about it.

 find

<T> T find(java.lang.Class<T> entityClass,
           java.lang.Object primaryKey)

In order to find an entity of class Person, you should use something like

find(Person.class, Object primaryKey)

As you have a composed key, you should have a IdClass or EmbeddedId like this.

public class PersonKey implements Serializable{

           String username;
           String emailId;

          public PersonKey(String username, String emailId){
                 //Add lines for correct constructor
           }
         //Override hascode and equals
}

Then you can find objects based on that key. find(Person.class, personKey);

your key need to be something like this.

PersonKey personKey = new PersonKey(1,1);
Person p = find(Person.class, personKey);

FIND DON'T ACCEPT LISTS IN PURE JPA !!, accept and return only ONE managed object. If you would use find to retrieve several objects you should call the method N times passed the keys you want to find.

If you use find passing a list you will see something like this.

org.springframework.dao.InvalidDataAccessApiUsageException: Provided id of the wrong type for class domain.model.Person. Expected: class domain.key.PersonKey, got class java.util.ArrayList; nested exception is java.lang.IllegalArgumentException: Provided id of the wrong type for class com.staples.sa.pricemart.domain.model.ItemFileEntity. Expected: class com.staples.sa.pricemart.domain.key.ItemFileKey, got class java.util.ArrayList

It seems eclipseLink have find that you can do that, but in order to make you application more portable try to use find as is described in JPA.